Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Strange behaviour of '@'-prefixed parameter values in ngResource resource action with GET #8948

@doronhorwitz

Description

@doronhorwitz

(found and tested in AngularJS v1.2.23)

When creating a custom $resource action, you can specify default params (using the params key) for that action with an object whose values can be prefixed with an '@'.
This allows you to call the resource action with params that specify a key with the same name as that that has an '@' prefix and it will get binded to that value when the action is called. But I believe the behaviour of it is strange. Here's the example:

var resource = $resource('/api/user/:userID/view', {}, {
    customAction: {
        method: 'GET',
        params: {
            userID: '@id'
        }
    }
});

resource.customAction({
    id: '1234'
});

The URL you expect to be called is:
/api/user/1234/view
but instead what actually gets called is:
/api/user/view?id=1234

And what's more, is if you change method to 'POST' (or 'PUT'), it works correctly, going to the first URL: /api/user/1234/view, meaning that this strange behaviour only happens for 'GET'

Now, I realise that this is the behaviour specified by the documentation (link):

If the parameter value is prefixed with @ then the value for that parameter will be extracted from the corresponding property on the data object (provided when calling an action method). For example, if the defaultParam object is {someParam: '@someProp'} then the value of someParam will be data.someProp.

... but why only the data object? Surely the values from the parameters should be used too? Especially since 'GET' methods don't allow for a request body.

I've stepped through the code which causes this behaviour and it occurs at line 524 of angular-resource.js in AngularJS v1.2.23:

route.setUrlParams(httpConfig,
                   extend({}, extractParams(data, action.params || {}), params),
                   action.url);

since only data is passed in as the first param to extractParams, only data will be used to replace any '@' values. So according to what I believe, as a first step, a combination of data and params should be passed in instead:

route.setUrlParams(httpConfig,
                   extend({}, extractParams(extend({}, params, data), action.params || {}), params),
                   action.url);

There would have to be a bit more work to remove any params which actually get binded to the '@' value, so that they don't appear after the '?' in the URL, but I would be happy to do this and make a pull-request for it, if someone can confirm my logic.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions