sp00m
sp00m

Reputation: 48817

Understanding the $resource factory and the @ prefix

Given the following service:

vdgServices.factory('UserService', ['$resource',
function($resource) {

    return $resource('api/users/:id', {}, {

        doGet: {
            method: 'GET',
            params: { id: '@userId' }
        },

        doPost: {
            method: 'POST',
            params: { id: '@userId' }
        },

        doPut: {
            method: 'PUT',
            params: { id: '@userId' }
        },

        doDelete: {
            method: 'DELETE',
            params: { id: '@userId' }
        }

    });

}]);

I observe the following requested URLs:

var params = { userId: 42 };
var onSuccess = function() { console.log("OK"); };
var onError = function() { console.log("KO"); };

UserService.doGet(params, onSuccess, onError);
// requests api/users?userId=42

UserService.doPost(params, onSuccess, onError);
// requests api/users/42

UserService.doPut(params, onSuccess, onError);
// requests api/users/42

UserService.doDelete(params, onSuccess, onError);
// requests api/users?userId=42

Can anybody explain why the :id URL parameter gets sometimes replaced by 42, sometimes not?

Ideally, I would like it to be replaced for any method, i.e. that the requested URL becomes "api/users/42" everytime.

Upvotes: 0

Views: 410

Answers (1)

Krzysztof Safjanowski
Krzysztof Safjanowski

Reputation: 7438

AngularJS $resource

If the parameter value is prefixed with @ then the value of that parameter will be taken from the corresponding key on the data object (useful for non-GET operations).

You have put params in the wrong place, you should implement like this

.factory('UserService', function($resource) {
    return $resource('api/users/:id', { id: '@id' }, {

        doGet: {
            method: 'GET'
        },

        doPost: {
            method: 'POST'
        },

        doPut: {
            method: 'PUT'
        },

        doDelete: {
            method: 'DELETE'
        }

    });
});

Lets test it

describe('userApp', function () {
    var UserService
      , $httpBackend
    ;

    beforeEach(function () {
        module('userApp');
    });

    beforeEach(inject(function (_UserService_, _$httpBackend_) {
        UserService = _UserService_;
        $httpBackend = _$httpBackend_;
    }));

    describe('User resource - api/users', function () {
        it('Calls GET – api/users/{id}', function() {
            $httpBackend.expectGET('api/users/42').respond(200);

            UserService.doGet({id: 42});

            $httpBackend.flush();
        });

        it('Calls POST - api/users/{id}', function() {
            $httpBackend.expectPOST('api/users/42').respond(200);

            UserService.doPost({id: 42});

            $httpBackend.flush();
        });

        it('Calls PUT - api/users/{id}', function() {
            $httpBackend.expectPUT('api/users/42').respond(200);

            UserService.doPut({id: 42});

            $httpBackend.flush();
        });

        it('Calls DELETE - api/users/{id}', function() {
            $httpBackend.expectDELETE('api/users/42').respond(200);

            UserService.doDelete({id: 42});

            $httpBackend.flush();
        });
    });
});

jsfiddle: http://jsfiddle.net/krzysztof_safjanowski/vbAtL/

Upvotes: 1

Related Questions