Remote Method on model based on User

603 views
Skip to first unread message

mayama takeshi

unread,
Mar 10, 2016, 5:23:56 PM3/10/16
to LoopbackJS
I am new to loopback. 
I am trying to add a remoteMethod 'greet' to model user (based on User)

// common/models/user.json 
{
  "name": "user",
  "plural": "users",
  "base": "User",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {},
  "validations": [],
  "relations": {
    "tweets": {
      "type": "hasMany",
      "model": "tweet",
      "foreignKey": "ownerId"
    }
  },
  "acls": [],
  "methods": {}
}

// common/models/user.js
module.exports = function(User) {
        User.greet = function(msg, cb ) {
                cb(null, 'Greetings... ' + msg);
        };

        User.remoteMethod(
                'greet',
                {
                        accepts: {arg: 'msg', type: 'string'},
                        returns: {arg: 'greeting', type: 'string'}
                }
        );
};

The greet method shows up in the explorer but if i try a POST request to it, I get:
    "message": "Shared class \"User\" has no method handling POST /greet?access_token=EQTxhBsZvVSNaxxsWdN3Mq6MgvBhYWZdD7k1raeV2BAlsOEb6kYYRMuvOtTg7tvW",
    "statusCode": 404,
But if I add the same method to a model based on PersistedModel, it works. Why?

Aurélie Violette

unread,
Mar 11, 2016, 11:20:04 AM3/11/16
to LoopbackJS
Try adding the method in your remote definie 

User.remoteMethod(
                'greet',
                {
                        accepts: {arg: 'msg', type: 'string'},
                        returns: {arg: 'greeting', type: 'string'},
                        http: {verb: 'post'}
                }
        );

Aurélie Violette

unread,
Mar 11, 2016, 11:23:13 AM3/11/16
to LoopbackJS
Nevermind, it is the default value.
It may due to the fact that you add it to an existing model.
A better way to do it it's to define MyUser model, based on user, and add the method to this custom model. This may fix you issue.
The method will not be added to User, but MyUser will have it, and also all method from User.

mayama takeshi

unread,
Mar 11, 2016, 4:26:39 PM3/11/16
to LoopbackJS
Hello,
thanks, but my custom model user is already based on model User provided by loopback.

Ebrahim Pasbani

unread,
Mar 12, 2016, 12:46:38 PM3/12/16
to LoopbackJS
Your `user` class has greet method, not `User` class

mayama takeshi

unread,
Mar 12, 2016, 4:10:33 PM3/12/16
to LoopbackJS

Yes. But the message 
  "Shared class \"User\" has no method handling POST /greet?access_token=EQTxhBsZvVSNaxxsWdN3Mq6MgvBhYWZdD7k1raeV2BAlsOEb6kYYRMuvOtTg7tvW"
is thrown by loopback when I try to access method user.greet and not User.greet (and the API explorer doesn't show User.greet anyway).

Here is a call using curl confirming it:

$ curl -s -x '' -X POST --header "Content-Type: application/x-www-form-urlencoded" --header "Accept: application/json" -d "msg=test" "http://localhost:3000/api/users/greet?access_token=cWFSSB9bRmoDSBAr4BteoM1SmhERl8cHJjgykjtLeEgkRaUTQBEHvr3JjbPrGCDQ" | python -m json.tool
{
    "error": {
        "message": "Shared class \"User\" has no method handling POST /greet?access_token=cWFSSB9bRmoDSBAr4BteoM1SmhERl8cHJjgykjtLeEgkRaUTQBEHvr3JjbPrGCDQ",
        "name": "Error",
        "stack": "Error: Shared class \"User\" has no method handling POST /greet?access_token=cWFSSB9bRmoDSBAr4BteoM1SmhERl8cHJjgykjtLeEgkRaUTQBEHvr3JjbPrGCDQ\n    at restRemoteMethodNotFound (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/strong-remoting/lib/rest-adapter.js:330:17)\n    at Layer.handle [as handle_request] (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/layer.js:95:5)\n    at trim_prefix (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/index.js:312:13)\n    at /home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/index.js:280:7\n    at Function.process_params (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/index.js:330:12)\n    at next (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/index.js:271:10)\n    at Function.handle (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/index.js:176:3)\n    at router (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/index.js:46:12)\n    at Layer.handle [as handle_request] (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/layer.js:95:5)\n    at trim_prefix (/home/takeshi/tmp/learn/loopback/test4/node_modules/loopback/node_modules/express/lib/router/index.js:312:13)",
        "status": 404,
        "statusCode": 404
    }
}

I would say loopback is failing to find the method in the descendant model (where it was defined) and is trying to locate it in the base model.

Ebrahim Pasbani

unread,
Mar 12, 2016, 4:28:26 PM3/12/16
to LoopbackJS
You should use different plural  for user class.
User class has "users" plural, so any calls to path /users/ gone to User class.
Set plural of user class to another thing.

mayama takeshi

unread,
Mar 12, 2016, 6:22:11 PM3/12/16
to LoopbackJS
Thanks, that was it.
I was mislead by API explorer as it showed the base URL of Base Model User as /Users so I was assuming /users and /Users would be different things.

Sabyasachi Dey

unread,
Jul 3, 2017, 11:57:46 AM7/3/17
to LoopbackJS, mayama...@gmail.com
Thanks for the post. I had the same issue!
Reply all
Reply to author
Forward
0 new messages