0

I've just worked around a strange bug. I'm sending in a REST PUT call with valid json and an application/json header.

The json in the PUT call is

{
    "gravatarURL":     "http://www.gravatar.com/avatar/?d=mm"
}

Any ideas on why valid json is not being recognised in req.params?

The code that handles the workaround parses the json body into params is

updateProfile: function(req, res) { 

    tag = 'UserController.updateProfile' ;

    user = {} ;
    user.id = req.session.userId ;
    if (!user.id){
        user.id = 0 ;
    }

    /* the following line of code should result in params with elements */
    params = req.params ;
    /* what I get is params == [] */

    /* this is the start of the workaround */
    if ( params.length == 0) {
        try {
            /* copying the body creates a valid json object */
            params = {}
            params.body = req.body ;
            params = params.body ;
            /* gravatarURL is the parameter sent in via the REST PUT call */ 
            user.gravatarURL = params.gravatarURL ;
        } catch (e){
            /* ignore and pass through to error with no params */
            console.log( tag + '.error: ' + e.message ) ;
        }
    } else {
        /* this is what I expect to be able to do */
        user.gravatarURL = req.param['gravatarURL'] ;
    }

    if ( user.id && user.gravatarURL) {
        console.log( tag + '.update.start' ) ;
        User.update({ id: user.id }, { gravatarURL: user.gravatarURL }, function(error, updatedUser) { 
            if (error) {
                console.log( tag + '.update.error: ' + error.message ) ;
                return res.negotiate(error); 
            } else {
                console.log( tag + '.update.finish: ' ) ;
                return res.json(updatedUser);   
            }
        });     
    } else {
        if ( !user.id ) {
            error = {} ;
            error.message = 'authorisation required. please login.' ;
            return res.badRequest({error:error}) ;
        }
        if ( !user.gravatarURL ) {
            error = {} ;
            error.message = 'gravatarURL: required' ;
            return res.badRequest({error:error}) ;
        }
    }

} ,
Keith John Hutchison
  • 4,955
  • 11
  • 46
  • 64
  • Can you at least mark the line it isn't working on or give the error or anything? – Datsik Feb 27 '16 at 04:05
  • @Datsik done. The really strange part is I have other code ... in the same module ... that works as expected. The put call is a postman is a duplicate of a similar code into the same module that works. – Keith John Hutchison Feb 27 '16 at 23:17
  • Have you tried [`req.allParams()`](http://sailsjs.org/documentation/reference/request-req/req-all-params)? According to the [docs](http://sailsjs.org/documentation/reference/request-req/req-params), `req.params` is "An object containing parameter values parsed from the URL path." so it should contain the url parameters only. If you're sending things in the request body, they won't be included in `req.params`. – Fissio Feb 29 '16 at 09:11

1 Answers1

1

Depending on how you make the call will depend on where the parameters show up on the request object (req).

Since you are sending a JSON object with the application/json header, the object gets added to req.body. Requests with a URL path will get added to req.params. Per the documentation req.params is 'an object containing parameter values parsed from the URL path. For example if you have the route /user/:name, then the "name" from the URL path will be available as req.params.name. This object defaults to {}.'

So if you want to access the parameter via req.params, you can change you request to '/updateProfile?gravatarURL=www.someurl.com otherwise if you pass a JSON object it will be available in req.body. So your workaround is redundant, as by design what you want to access is already safely in req.body.

The docs don't do the best job of explaining this, but with a little trial and error it's easy to find out where your passed values are showing up on the request object.

Ian Kidd
  • 66
  • 3