If you look at demos around using $resource in Angular then you'll see code something like this
app.factory("issuesResource", function ($resource) { return $resource('/api/issues/:id', { id: "@id" }, { update: { method: 'PUT' } }); });so, what does this do/mean.
Breaking it down:
app.factorycreates a factory. Normally you would see something like this:
app.factory("myFactory", function(){ return { doSomething: function(){} }; });so when creating a $resource based service the code looks a little odd, it returns $resource(), so what does the call to $resource do?
$resource is "A factory which creates a resource object" according to the documentation, so what our code does is to take $resource (already a factory) and wrap it in our factory and then extend it. We extend it by telling it what the base URL is ('/api/issues' in this case), telling it where to get an 'id' value from when needed (more on this is a moment) and extending it with our own methods.
The last object passed to $resource
update: { method: 'PUT' }adds an 'update' method to $resource and causes $resource to use an HTTP PUT when this method is called.
The other parameter
{ id: "@id" }is more interesting. According to the documentation then: "If the parameter value is prefixed with @ then the value of that parameter is extracted from the data object (useful for non-GET operations)." So this implies that the parameter is not used for GETs, and indeed this is so. I have a spec that looks like this:
it("should return an object when get is called", inject(function (issuesResource) { httpBackend.expectGET("/api/issues/1").respond(200, {id: 1}); var issues = issuesResource.get({id: 1}); httpBackend.flush(); expect(issues.id).toBe(1); }));and this works whether the '@id' parameter is in place or not. For GETs it's the name of the placeholder in the URL that matters, so the 'id' in the '/api/issues/:id' has to match the 'id' in the call to
issuesResource.get({id: 1});, however this is not true for POST, PUT or DELETE. In these cases the presence and name of the '@id' value is important.
So if we have a test for POST spec that looks like this:
it("should use the id passed in the object when posting", inject(function (issuesResource) { httpBackend.expectPOST("/api/issues/1").respond(200, {id: 1}); var issues = issuesResource.save({id: 1}); httpBackend.flush(); expect(issues.id).toBe(1); }));then in the call to save the name of the property ('id') must match the name defined when creating the factory.