MEANJS user profile functionality

大兔子大兔子 提交于 2019-12-05 17:28:57

I finally figured it out and I'd like to put solution here in detail. I'm not sure this is the best way, but this is how I did. Any suggestions are welcome. Let's start.

Since we want to use .../user/username URL structure, we first need to add these lines to users.server.route.js file.

app.route('/api/users/:username').get(users.read);
app.param('username', users.userByUsername);

Now we have to add our userByUsername middleware into users.profile.server.controller.js:

/*
* user middleware
* */
exports.userByUsername = function(req, res, next, username) {
User.findOne({
    username: username
}, '_id displayName username created profileImageURL tagLine').exec(function(err, user) {
    if (err) return next(err);
    if (!user) return next(new Error('Failed to load User ' + username));
    req.user = user;
    next();
});
};

You may have not tagLine field in your collection, or you may have other custom fields. So remember to change that part and include or exclude desired fields. Never leave empty that part. Because, you wouldn't want to get all user information, including e-mail, password hash etc for security reasons. Any signed in user can reach this information, just by knowing username.

At this point when we type .../api/users/username in the address bar of our browser, we must get the correct json. This is good, but we also want to get posts belong to this user. So we need to do something like this for the posts.

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);
}
});
};

Now when you type .../api/posts/of/userid in your address bar, you must get correct json of posts of userid.

So the next step is do the client side job, and connect to REST endpoints.

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!');
               });
           }
       );
    };

}
]);

I didn't create a new angular route for posts. As you can see I used an AJAX request to pull the posts. I've considered other options, such as creating a directive etc. In the end, I find this way most comfortable.

That's all. Now you can open your view file, view-profile.client.view and start to decorate. You can reach ourUser and userPosts there. And the URL of this profile page is: .../users/username.

I hope this helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!