5

my RESTful API returns an array:

GET /test => [1367297123312,1.0,2.0,3.0,100]

I have a service:

(angular
 .module('app.services', ['ng', 'ngResource'])
 .factory('myData', [
     /******/ '$resource',
     function ($resource) {
         return $resource('test');
     }])
);

In my controller I need to get the numbers. I tried:

(angular
 .module('app.controllers', ['ng', 'app.services'])
 .controller('tweetsapiContr', [
     /******/ '$scope', 'myData',
     function ($scope,   myData) {
         myData.get({}, function (data) {
             console.log(data);
         };
     }
 ])
);

The above gives me TypeError: Object #<h> has no method 'push' error, and if I use query instead of get on the service, it returns an array of objects that have methods like $get, $save etc, but calling $get for example returns undefined.

How to get the numbers? Responding with a hash from the server works, but I am trying to figure out how to make it work with arrays.

akonsu
  • 28,824
  • 33
  • 119
  • 194

4 Answers4

8

A resource "class" object with methods for the default set of resource actions optionally > extended with custom actions. The default set contains these actions:

{ 'get':    {method:'GET'},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'} };

So you have two options:

Set a custom method on the resource object:

$resource("/url/:someParam", {}, {
    getMyArray: {method:"GET", params: {someParam:"hello"}, isArray: true}
});

Use query method

Resource object has a query method which is defined with isArray: true as you can see in the top of the answer.

Please be advised that responding with a top level array to a GET method has security vulnerabilities as array constructors can be redefined.

Read those: JSON security best practices? What are "top level JSON arrays" and why are they a security risk?

Community
  • 1
  • 1
Umur Kontacı
  • 35,403
  • 8
  • 73
  • 96
7

This open issue (#4314) has good information about why numbers (and other primitive data types like strings) cannot be parsed by $resource.

From what I understand, $resource needs to work on objects so that it can attach it's methods (get, query, post, etc...). If all you are trying to do is to read the array and never need to 'update' it, they recommend using just straight up $http.

Hope that helps clear things up and points future readers of this question in the right direction for best practices in dealing with arrays over a REST api.

jlee
  • 464
  • 6
  • 9
5

You can add a custom action to the resource with isArray: true; (resource docs)

return $resource('test', {}, {
  getArray: { method: 'GET', isArray: true } 
};

Then I believe you have to call it with a dollar sign myData.$getArray

Bogdan Rybak
  • 2,107
  • 1
  • 19
  • 22
  • I don't think you are using it correctly, when you call resource get the object should evaluate to your data. Try `var myArray = myData.query(); console.log(myArray)` – Bogdan Rybak Apr 30 '13 at 05:43
  • 1
    this won't work because the resource returns a promise object which is populated later when the response comes back. – akonsu Apr 30 '13 at 05:45
2

You should not return JSON arrays since they are vulnerable to cross site attacks. Read this article for the why part http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx

Return an object with the array attached to a property. This will mitigate potential attacks and solve your problem in one go.

{
    d: [1,2,3,4,5]
}


myData.get({}, function (data) {
    console.log(data.d);
};

Still want the array?

You can restructure the actions of a resource and set the isArray property of the action to true.

Angular ngResource docs

var actions = { 
  'get':    {method:'GET', isArray:true},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'} 
};

$resource(url[, paramDefaults][, actions]);
Bart
  • 17,070
  • 5
  • 61
  • 80
  • 1
    yes, I have read the article before. I am still interested to figure out how to fetch arrays. I think this is not a problem with arrays, but with the numbers. – akonsu Apr 30 '13 at 05:36
  • i also think there is some problem with handling numbers – Ajay Beniwal Apr 30 '13 at 05:49