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.
No comments:
Post a Comment