Building on the self-answer to this excellent question: MEANJS user profile functionality. They wanted to add the functionality to the meanjs scaffold that you can navigate to any user's page and you'll get essentially a profile page with a list of all of their posts. It seems to work fine.
I wanted to add a "findOne()" equivalent method here - so that for each article/post that's listed, if we click on it, we'll have more options specific to the retrieved information about each article.
However, and maybe it is a simple mental block I've created myself because I'm so inexperienced, I can't really think of how to implement this in their structure.
For example, see their code:
"I added this line to posts.server.routes.js:
app.route('/api/posts/of/:userid').get(posts.listOf);
... and this part to posts.server.controller.js:
exports.listOf = function(req, res) { Post.find( { user: req.params.userid }).sort('-created').exec(function(err, posts) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(posts);
}
});
};
So - would I put a findOne method here, since listOf is essentially a "find" method? The thing is - the routing and routeparams/stateparams becomes unclear to me then. IE - is the applicable server route now /api/posts/of/:userid/:postid
? And then the method query uses { user: req.params.userid }, { post = req.params.postid }
? That makes sense conceptually, but I'm not sure if I'm allowed to use multiple routeParams in that way. And if I'm not mistaken - this only covers creating the restful endpoints, right?
For client side, from their SO question/answer:
"Open users.client.routes.js and add this:
state('users', {
url: '/users/:username',
templateUrl: 'modules/users/views/view-profile.client.view.html'
});
Template Url points to newly created html file which I want to use for user profile page. So create this file under client/views folder:
<div class="col-md-12" data-ng-controller="ViewProfileController" data-ng-init="findUser()">
...
{{ ourUser }}
<hr />
{{ userPosts }}
....
You can fill this file as you like. I created a new controller for this view. As you can see its name is ViewProfileController. And I have a findUser function to do the job. Here is the controller code:
'use strict';
angular.module('users').controller('ViewProfileController', ['$scope', '$http', '$location', 'Users', 'Authentication', '$stateParams',
function($scope, $http, $location, Users, Authentication, $stateParams) {
$scope.user = Authentication.user;
$scope.findUser = function () {
$scope.ourUser = Users.get({
username: $stateParams.username
}).$promise.then( function(ourUser) {
var userPostsPromise = $http.get('api/posts/of/' + ourUser._id);
userPostsPromise.success(function(data) {
$scope.userPosts=data;
$scope.ourUser=ourUser;
});
userPostsPromise.error(function() {
alert('Something wrong!');
});
}
);
};
}
]);
(end of content cited from their post)
I think I understand this controller function "findUser": find the username associated with the url request, then find their posts based on an http GET request to the RESTful endpoint created above, @ the 'api/posts/of' + username._id
. But, again, how do we add findOne() to this? This seems like where a more simple solution fits - but I don't know how to integrate their solution with what I would do normally for a client-side findOne():
articles.client.controller.js:
$scope.findOne = function() {
$scope.article = Articles.get({
articleId: $routeParams.articleId
});
(Or I guess $stateParams since the SO answer I linked uses ui-router).
And the Articles service client-side would be:
articles.client.service.js:
angular.module('articles').factory('Articles', ['$resource', function($resource) {
return $resource('api/articles/:articleId', {
articleId: '@_id'
}, {
update: {
method: 'PUT'
}
});
}]);
For my $scope.article
, could I .get by article ID referenced in the list of articles in the view (a la the other poster's solution) and ignore the user/posts routing structure when you go to findOne()? So I would use their structure for the ._id of a post, and then when the user clicks on it for more detailed options, it routes client-side to api/posts/:postid
(no user)? Still not sure how to do that, or if it's stupid and I should stick with api/:user/posts/:postid
or (api/:user/:postid
)? How do I use multiple routeparams here (note that that's only a part of the question)?
Edit: Or should it be static methods, like:
UserSchema.statics.findOneByUsername = function (username, callback) {
this.findOne({ username: new RegExp(username, 'i') }, callback);
};
Now Im even more confused.
Thanks