Loopback: How to add remote methods to the User model

Created on 10 Nov 2014  路  8Comments  路  Source: strongloop/loopback

I'd like to expose a method as rest api method but the documentation seems to be mostly referring to loopback 1.0. and my attempts were not successful. I'm using strongloop v2.9.2.

my intention is to expose the api as :

/users/{id}/mycarddetails/{fk}
  • The api is supposed to be a wrapper for /users/{id}/mycards/{fk} with {include: "details" } as filter.
  • The api should return an instance of mycard with a relation "details" (mycard -> card-details) expanded.
  • The api is restricted to the $owner.

The basic code I wrote (models/user.js):

module.exports = function(User) {

  User.mycarddetails = function(fk, cb) {
    cb(null, { name: 'test'});
  };

  User.remoteMethod(
    'mycarddetails',
    {
      description: 'Get the user card details by id',
      accepts: [
        //{ arg: 'id', type: 'number', required: true, description: 'User id'},
        { arg: 'fk', type: 'number', required: true, description: 'Foreign key for mycards' },
      ],
      http: { verb: 'get', path: '/mycarddetails/{fk}'},
      isStatic: false,
      returns: { arg: 'UserCard', type: 'object'}
    }
  );

};

This is what I get as a result:
screen shot 2014-11-10 at 1 05 01 pm

Notice that 1) the request url is not properly generated. 2) the method is not mapped.

I know things changed a bit around in loopback 2.0. What is your suggestion in this case?

Most helpful comment

I figured it all and here's my working code for others looking for a working implementation:

  User.prototype.cardDetails = function(fkId, cb) {

    var UserCard = app.models.UserCard;
    var userId = this.id;
    var filter = {
      include: 'details',
      where: { id: fkId, userId: userId }
    };
    UserCard.findOne(filter , function(err, userCard) {
      if (!userCard) {
        err = new Error('No instance with id ' + fkId + ' found for ' + UserCard.modelName);
        err.statusCode = 404;
        return cb(err);
      }
      cb(err, userCard);
    });
  };

  User.remoteMethod(
    'cardDetails',
    {
      description: 'Get the user card details by id',
      accepts: [
        { arg: 'fk', type: 'number', required: true, http: { source: 'path' }, description: 'Foreign key for mycard' },
      ],
      http: { verb: 'get', path: '/cardDetails/:fk'},
      isStatic: false,
      returns: { arg: 'result', type: 'UserCard' }
    }
  );

All 8 comments

I got the definition working as so:

  User.prototype.mycarddetails = function(fk, cb) {
    cb(null, { name: 'test'});
  };

  User.remoteMethod(
    'mycarddetails',
    {
      description: 'Get the user card details by id',
      accepts: [
        { arg: 'fk', type: 'number', required: true, http: { source: 'path' }, description: 'Foreign key for mycards' },
      ],
      http: { verb: 'get', path: '/mycarddetails/:fk'},
      isStatic: false,
      returns: { arg: 'result', type: 'UserCard' }
    }
  );

Now, I need to fetch the passed user id. Any idea how to get it from the defined handler?

I figured it all and here's my working code for others looking for a working implementation:

  User.prototype.cardDetails = function(fkId, cb) {

    var UserCard = app.models.UserCard;
    var userId = this.id;
    var filter = {
      include: 'details',
      where: { id: fkId, userId: userId }
    };
    UserCard.findOne(filter , function(err, userCard) {
      if (!userCard) {
        err = new Error('No instance with id ' + fkId + ' found for ' + UserCard.modelName);
        err.statusCode = 404;
        return cb(err);
      }
      cb(err, userCard);
    });
  };

  User.remoteMethod(
    'cardDetails',
    {
      description: 'Get the user card details by id',
      accepts: [
        { arg: 'fk', type: 'number', required: true, http: { source: 'path' }, description: 'Foreign key for mycard' },
      ],
      http: { verb: 'get', path: '/cardDetails/:fk'},
      isStatic: false,
      returns: { arg: 'result', type: 'UserCard' }
    }
  );

Can you please close the issue if it is resolved

sure, wanted to give it time to get noticed in case someone had something to say.

It's not working for me. signup doesn't showup in the explorer. Can anyone please help?

module.exports = function(User) {

User.prototype.signup = function(userData, callback){
    // Validate data
    // Save data - User
    // Create role mapping
    // return token
}
 User.remoteMethod(
    'signup', 
   {
     accepts: [{ arg: 'userData', type: 'object' }],
     returns: { arg: 'token', type: 'object' },
     http: { verb: 'post' }
   });
}

@inawlaljar you probably already figured this out, but you are missing isStatic: true:

 User.remoteMethod(
    'signup', 
   {
     isStatic: false,
     accepts: [{ arg: 'userData', type: 'object' }],
     returns: { arg: 'token', type: 'object' },
     http: { verb: 'post' }
   });
}

im using loopback over strongloop, when i make the remote method from my model user.js, exactly the same way than you makes, nothing happen, i need to setup any other file to it work?

@diegomoura637 Please open your own new issue for us to resolve it. We usually don't check closed issues. However, in your case you need to extend the builtin User model to add remote methods. See https://github.com/strongloop/loopback-example-user-management/blob/master/common/models/user.json#L2-L3 and https://github.com/strongloop/loopback-example-user-management/blob/master/common/models/user.js#L4.

Was this page helpful?
0 / 5 - 0 ratings