9

I have this endpoints

/clients/:id
/bills/:id
/clients/:id/bills

I'm trying to create some resources with angular-resource to represent my API.

Clients and Bills Resources

I created a resource for the clients,

.factory('Clients', function($resource){
   return $resource('/clients/:id')
})
.factory('Bills', function($resource){
   return $resource('/bills/:id')
});

Those worked fine.

The Problem

My problem is when I wanted to define a resource to represent the bills of a client calling the endpoint /client/:id/bills

I thought that this should be a Bills resource with a method getFromClient() or something like that, as it will return an array of Bills from the client. But I have already use the Bills name. And the endpoint is different to the one already defined.

Any idea how to structure this?

2
  • Why not passing two variables to the client? Something like id and bills? If you leave the last one undefined you just get everything from a certain client and if its true you only get its bills. Commented Mar 25, 2013 at 21:13
  • @Flek But if I pass variables to the Clients service is going to return Client resources instead of Bill resources (with the Clients methods) Commented Mar 25, 2013 at 21:58

2 Answers 2

18

I think what I was loooking for is now in Anguar 1.1

.factory('Bills', function($resource){
  return $resource('/bills/:id',{}, {
    get: {
      method: 'GET',
      params:{
        clientId: '@clientId'
      }
    },
    'getFromClient': {
      method:'GET',
      params: {
        clientId: '@clientId'
      },
      url: host + "/clients/:clientId/bills",
      isArray: true
     }
   })
});

Now you can add a url property to the method declaration to override the main url.

If you want to go with a library that enable you to solve this problema and many others, you could try https://github.com/platanus/angular-restmod

Here is an example:

.factory('Client', function(restmod){
    return restmod.model('clients', {
        bills: { hasMany: 'Bill' }
    });
}

.factory('Bill', function(restmod){
    return restmod.model('bills');
}

.controller('myController', function(Client){
    $scope.client = Client.$find(1);
    $scope.client.bills.$search();
});
Sign up to request clarification or add additional context in comments.

1 Comment

Can you link to the documentation that explains this?
5

Check the ngResource docs... Scroll down to the first example heading: http://docs.angularjs.org/api/ngResource.$resource

It's kinda confusing because they're not doing it right in the example... lol

I believe it would look something like:

.factory('Clients', function($resource){
   return $resource('/clients/:id', {id:'@id'})
})
.factory('ClientBills', function($resource){
   return $resource('/clients/:clientId/bills/:id', {clientId:'@clientId', id:'@id'})
});

I haven't tested this, but I think that's right. =)

UPDATE

You would then access them like so:

.controller('MyCtrl', function ($scope, $routeParams, Clients, Bills) {
    $scope.client = Clients.get({id:$routeParams.clientId})
    $scope.bills = ClientBills.get({clientId:$routeParams.clientId})
})

I also changed the name of the service to "ClientBills", as it is more specific to the task, and you may want a "Bills" service that doesn't require a client id...

2 Comments

Thanks thom and @max, I think is a good way to go if I need to go with angular 1.0
I think you'd want to call ClientBills.query(..) though, since it will be returning an array of bills

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.