Search code examples
mongodbmean-stackmeanjs

Immediate default api call done when selecting list - MEAN.JS


Instead of the basic CRUD module articles that is given, I have a similar one called friends. A friend is simply another user but is separate from the user module. I'm trying to make it so when a user selects to see the list of friends, they see THEIR OWN list of friends and not all of the ones stored in the friends collection in mongo. The structure of a friend in the mongo collection is:

{
    "_id" : ObjectId("587b9e16d1bdf314181b354e"),
    "user" : ObjectId("5867c5e92fa4e91008788f80"),
    "added" : ISODate("2017-01-15T16:06:46.975Z"),
    "friend" : {
        "firstName" : "b",
        "lastName" : "b",
        "email" : "b@b.com",
        "profileImageURL" : "modules/users/client/img/profile/default.png",
        "roles" : [
               "user"
        ],
        "created" : "2017-01-11T17:28:19.849Z",
        "__v" : 0,
        "username" : "bbbbbb",
        "provider" : "local",
        "displayName" : "b b",
        "_id" : "58766b337f091f842addfd5a"
    },
    "__v" : 0
}

So the user field is the user which this friend is assigned to and the friend object is the actual friend.

I got the api call working easily enough by just adding another route which takes the user as a parameter:

/api/:userId/friends/:friendId

/api/:userId/friends

I've realised that (and this is something that is default in MEAN.JS), in the client, if a user selects to see the list of friends, the call is immediately made to see ALL (/api/friends) friends in the collection in mongo.

I've looked all through the client but cannot see where this call is made!

What I want to do is find where this call is made and change it so that it includes the :userId as a param so only getting that users friends.

As it looks to me, as soon as you hit the template to view friends, the controller should make a ngResource query to the FriendsService to get the friends of a specific user:

function FriendsService($resource) {
    return $resource('api/:userId/friends/:friendId', {
        userId: '@user',
        friendId: '@_id'
    }, {
        update: {
            method: 'PUT'
        }
    });
}

...but obviously this is not the case.

EDIT:

I am happy that the $stateProvider is setup in the config of the friends module client side:

$stateProvider
    .state('friends', {
        abstract: true,
        url: '/friends',
        template: '<ui-view/>'
    })
    .state('friends.list', {
        url: '',
        templateUrl: 'modules/friends/client/views/list-friends.client.view.html',
        controller: 'FriendsListController',
        controllerAs: 'vm',
        data: {
            pageTitle: 'Friends List'
        }
    });

So when I hit the url /friends, what should happen as there is no controller or template associated with it?

However, in friends.client.config.js, the menu service is:

// Add the dropdown list item
menuService.addSubMenuItem('topbar', 'friends', {
    title: 'List Friends',
    state: 'friends.list'
});

So my understanding is that when the sub-menu option to list friends in the UI is clicked, it uses that state which maps to the FriendsListContoller.

function FriendsListController(FriendsService) {
    var vm = this;

    vm.friends = FriendsService.query();
}

So will query the ngResource of the FriendsService. The FriendsService:

function FriendsService($resource) {
    return $resource('api/:userId/friends/:friendId', {
        userId: '@user',
        friendId: '@_id'
    }, {
        update: {
            method: 'PUT'
        }
    });
}

So it looks like to me that when a user selects to see the list of friends, /api/:userId/friends/:friendId should be called.

The point is that I can see in my console that when selecting to view the list of friends, the call /api/friends is being made instead which gets all friends in the collection in mongo no matter who they are assigned to:

enter image description here

The call is clearly being made from the client somewhere but cannot find where.

3 questions:

  1. Is my logic correct? In the sense that when a user selects to view the list of friends, the service is queried?
  2. In the service, the params userId and friendId are set to @user (which I set) or @_id (which was already there). My presumption was that these are the fields in the collection in mongo, is that right? Is there anyway I can debug the values that are passed into this call?
  3. Where is the call '/api/friends` being made? As, logically in my head, I cannot find where it is being called in the client (probably because I do not know enough of the MEAN.JS structure yet)

Solution

  • The fix was relatively simple and I feel stupid for not thinking of this before.
    MEAN.JS has an Authentication factory which can return the current user within the session (Authentication.user)
    Just by using Authentication.user._id as the parameter for the userId in the REST call, I was able to do it. Here's my new FriendsService:

    function FriendsService($resource, Authentication) {
        return $resource('api/:userId/friends/:friendId', {
            userId: Authentication.user._id,
            friendId: '@_id'
        }, {
            update: {
                method: 'PUT'
            }
        });
    }