Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: $resource with nested resources

I am using AngularJS $resource model to REST API. I have got something like this:

angular.module('libraryapp')
    .factory('Book', function($resource){
        return $resource('books/:id');
    });

I am using in these way:

Book.get({ id: 42 }, function(book) {
    console.log(book);
});

But I also want an endpoint to a subresource, let's say:

GET /books/:id/comments

How should I define it in module? May I extend Book in some way, to use it like this

Book.get({ id: 42 }).Comment.query(function(comments) {
    console.log(comments);
});
like image 790
Dariusz Mydlarz Avatar asked Nov 14 '14 10:11

Dariusz Mydlarz


2 Answers

You can easily reach nested RESTful resources with AngularJS $resource definitions.

The clue is to understand how the params parameter of each action definition (in the list of actions) in the $resource definition works. As the documentation says, it's an

Optional set of pre-bound parameters for this action. […]

angular.module('libraryApp').factory('Book', [
  '$resource', function($resource) {
    return $resource('books/:id/:subResource', {}, {
      comments: {  // The `comments` action definition:
        params: {subResource: 'comments'},
        method: 'GET'
      }
    });
  }
]);

Given the above definition, you should still be able to use Book as before. For example Book.get({ id: 42 }) translates to a GET books/42/ request.

However, given the new :subResource part of the $resource URL ('books/:id/:subResource'), you now can generate a

GET books/42/comments

request by calling either Book.get({ id: 42, subResource: 'comments' }) or the much more short and elegant interface Book.comments({ id: 42 }) defined as your comments action.

like image 74
Martin Thorsen Ranang Avatar answered Sep 27 '22 22:09

Martin Thorsen Ranang


As far as I know, you can't nest resources, but it's pretty simple to do what you're looking for:

You can define optional parameters which you can override in each resource (like category here) or even override the url (look at the otherUrl resource)

angular.module('libraryApp').factory('Book', [
  '$resource', function($resource) {
    return $resource('books/:id/:category', {}, {
      comments: {
        method: 'GET',
        action: 'category'
      },
      otherUrls: {
        method: 'GET',
        url: 'books/:id/admin/:option'
      }
    });
  }
]);
like image 39
kumarharsh Avatar answered Sep 27 '22 20:09

kumarharsh