1

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

Community
  • 1
  • 1
  • Did you ever get a working solution to this? I cant even get the list of posts working as it throws an error with the $http.get('api/posts/of/' + ourUser._id); saying that it expects an object but gets an array. – ChrisM Feb 08 '16 at 18:34

0 Answers0