ikamatovic
ikamatovic

Reputation: 43

Angular.js $resource result

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

Answers (3)

k0nG
k0nG

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

Michelle Tilley
Michelle Tilley

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

Chandermani
Chandermani

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

Related Questions