Reputation: 43
I found very strange behavior of Angular $resource. Please checkout following lines of code:
class Service
constructor: ($resource) ->
service = $resource '/record/:id'
Service::list = (cb) ->
service.query().$promise.then (data) ->
#result: data == [e, $promise: Object, $resolved: true]
cb data
Service::get = (id, cb) ->
service.get(id:id).$promise.then (data) ->
#result: data == {id: 1, name: 'name' ...}
cb format data
Service "get" method returns correct value (object) sent by server, but the "list" method as result return array which contains $promise and $resolved...
Does anyone has some logic explanation?
UPDATE:
I found the problem. Service result is array of strings and that cause as result array of sting chars. This can be solved by using $http instead of $resource.
Ex:
server-side -> ['list', 'of', 'elements']
client-side -> ['l','i','s','t']
Upvotes: 2
Views: 4096
Reputation: 5076
If like me you'd like your response to give you the data without the extra $promise and $resolved attributes you can modify the resource and add an 'interceptor' as described here: http://docs.angularjs.org/guide/migration#resource-promises-are-resolved-with-the-resource-instance
For a get it will look like this:
var Resource = $resource('/url', {}, {
get: {
method: 'get',
interceptor: {
response: function(response) {
// expose response
return response;
}
}
}
});
Then you can access the response object rather than the resource instance when you make a get request. For example:
Resource.get(function(response){
angular.forEach(response.data, function(value, key){
}, $scope.varName);
});
This also means you can access other response attributes like response.status
, response.headers
as well as getting the instance of the resource with response.resource
.
Upvotes: 5
Reputation: 159095
but the "list" method as result return array which contains $promise and $resolved
Double check this--the way Chrome displays arrays inside a console.log
when the array has extra properties is misleading. For example, try the following in the Chrome console:
> a = [1, 2, 3]
> a.$promise = 'thing'
> a.$resolved = true
> a
[1, 2, 3]
> console.log(a)
[1, 2, 3, $promise: "thing", $resolved: true]
As you can see, it lists $promise
and $resolved
as elements of the array, even though they're not actually in the Array.
Upvotes: 2
Reputation: 42669
The documentation itself mentions about this and it's usage
The Resource instances and collection have these additional properties:
$promise: the promise of the original server interaction that created this instance or collection.
On success, the promise is resolved with the same resource instance or collection object, updated with data from server. This makes it easy to use in resolve section of $routeProvider.when() to defer view rendering until the resource(s) are loaded.
On failure, the promise is resolved with the http response object, without the resource property.
$resolved: true after first server interaction is completed (either with success or rejection), false before that. Knowing if the Resource has been resolved is useful in data-binding.
Upvotes: 0