John Dorean
John Dorean

Reputation: 3874

Saving subresource with Angular's $resource

I have a factory defined which returns a $resource:

myApp.factory('Region', function($resource) {
    return $resource(baseUrl + '/templates/:templateId/regions/:regionId', null, {
        query: {
            method: 'GET',
            isArray: false
        },
        update: {
            method: 'PUT'
        }
    });
});

As you can see, a region is a subresource of a template, and I've defined the endpoint as /templates/:templateId/regions/:regionId.

My issue comes when I want to save a new region. How do I specify the templateId to save the region to? Here's my snippet:

$scope.save = function() {
    if ($scope.mode === 'edit') {
        // TODO
    } else {
        Region.save($scope.region, function(success) {
            $state.go('app.templateList')
        });
    }
};

In every other resource I have I've just used Model.save($scope.model);, I don't know how to specify other URL parameters and the Angular docs don't seem to cover it.

Upvotes: 2

Views: 243

Answers (2)

ciekawy
ciekawy

Reputation: 2337

I've faced similar dillema. I thought about some generic convention where to create subresource X eg as a new element of a collection owned by some resource Y I would do

POST /api/Y/<yId>/X

then to access collection of X owned by Y:

GET /api/Y/<yId>/X

However for modifying or deleting subresource we could access subresource directly:

PUT /api/X/<xId>
DELETE /api/X/<xId>

to achieve above we could use $resource definition as

Subresource = $resource('/api/:parent/:parentId/subresource/:id', 
  { id: '@id' }, 
  {
    'update': { method:'PUT' } // this is because Angular lacks PUT support
  });

then we can use it like

var subresourceList;
Subresource.query({parent: 'Y', parentId: parentId }, 
  function(result) {
    // handle result here
    subresourceList = result;
  });

and after modifying single subresource object we can save it using

var subresource = subresourceList[0];
subresource.someProp = 'newValue';
subresource.$update()

with earlier subresource definition the $update will do PUT directly to /api/X/<xId> which is reasonable whenever subresource X object in terms of being modified has nothing to do with its owning Y.

Upvotes: 0

just-boris
just-boris

Reputation: 9776

According the docs, non-GET (e.g. PUT) methods accepts following arguments

Resource.save([parameters], postData, [success], [error]).

Where parameters is a path params and it is optional, postData – body of the request. If you want to provide templateId, just add it as first argument:

Region.save({templateId: 'id'}, $scope.region, function(success) {
    $state.go('app.templateList')
});

Upvotes: 2

Related Questions