Reputation: 508
I want to use a style like:
http: //mysite/performer_ratings/guitar-players
instead of typical mongo ids in urls:
http: //mysite/performer_ratings/56623de898tt752ae45
I'm using angular ui-router successfully to use ui-srefs to create either, and load the template I want.
my issue is that I can't figure out how to take the formatted name from the request and use it to retrieve the topic object I need. (btw, I use the property named "topic_url" to store "guitar-players" instead of the name "Guitar Players")
I -can- get the app working with ugly urls with the following:
//view controller
$http.get('api/topics/' + $stateParams.id).success(function(topic){
$scope.topic = topic;}
and
// api/topic/topic.controller
// Get a single topic
exports.show = function(req, res) {
Topic.findById(req.params.id, function (err, topic) {
if(err) { return handleError(res, err); }
if(!topic) { return res.status(404).send('Not Found'); }
return res.json(topic);
});
};
but I can't do this:
//view
// Get a single topic
exports.show = function(req, res) {
$http.get('api/topics/' + $stateParams.topic_url).success(function(topic){
$scope.topic = topic;
});
};
//in api/topic/topic.controller
exports.show = function(req, res){
Topic.findOne({topic_url: req.params.topic_url}, function(err, topic){
if(err) { return handleError(res, err); }
if(!topic) { return res.status(404).send('Not Found'); }
return res.status(200).json(topic);
});
};
I can't get a good look at the req object to know how to access it's contents and googling hasn't helped me there.. which could be the simple thing that solves my problem.
I'm up for alternative ways to use a name-type property in my urls instead of the object ids
Thanks in advance.
Upvotes: 0
Views: 243
Reputation: 508
By trial and error I found the way to make my show request work with the "prettier" params.
the key was using: req.params.id instead of req.params.user_url
that even though my ui-router set-up was like:
.state('performer_rating', {
url: '^/performer_rating/:topic_url',
templateUrl: 'app/topic/performer_rating.html',
controller: 'PerformerRatingCtrl'
});
and my html creating the http: //mysite/performer_ratings/guitar-players style url was like this:
<li class="topic-pills" ng-repeat="rating_topic in list_topics" ng- class="{active: isActive('{{rating_topic.topic_url}}') }">
<a ui-sref="performer_rating({topic_url:rating_topic.topic_url})">{{rating_topic.title}}</a>
</li>
I guess mongoose takes the portion of the url after the final "/" and assigns it to params.id even though I was calling it :topic_url in the $stateProvider config ?
I suppose that makes sense enough now that I've figured it out. The view controller does indeed use the :topic_url but the api controller calls the last part ".id" no matter what. (Its also interesting that it is .id , not ._id ...the underscore needed to access the id with an object)
I also seem to have preserved the function of the REST api with a conditional if(req.params.id) ?wouldn't that always be true? even though I mucked with it:
// Get a single topic
exports.show = function(req, res) {
if(req.params.id){
// handles pretty urls
Topic.findOne({topic_url: req.params.id}, function(err, topic){
if(err) { return handleError(res, err); }
if(!topic) { return res.status(404).send('Not Found'); }
return res.status(200).json(topic);
})
}else{
Topic.findById(req.params.id, function (err, topic) {
if(err) { return handleError(res, err); }
if(!topic) { return res.status(404).send('Not Found'); }
return res.status(200).json(topic);
});
}
};
! I'd still love feedback from others to know if there is a better "angularjs way" to accomplish my url style goal.
Upvotes: 2