-
Notifications
You must be signed in to change notification settings - Fork 27.5k
$resource throws TypeError when json has both properties and arrays #1044
Comments
This only happens when a Query is done instead of a Get. |
I had this same problem. It went away when I had my server return a JSON array at the top level, rather than an object. It makes some sense to assume that .query would normally return an Array, although I can think of situations where I'd want .query to return an object like: {
results: [...],
pagination: {
prev: http://...,
next: http://...
}
} Looking at the declaration of the default actions for "query", it looks like you can override isArray to false. I haven't tried it myself though. |
I ran in to what appears to be the same issue. The json was an array of objects:
It gave me a stack trace like this:
This was doing a get(). |
this is expected behavior. When your JSON returns an array, use |
Ah, that makes sense. I was going to blame the docs, but on second inspection they're perfectly lucid on the matter. Thanks. |
Looks someone else bumped into the same recently: #1689. |
AndrewO, you can pass metadata in custom response headers, then retrieve them from the header getter function that is passed as the second argument to the success callback. |
Ran into @AndrewO's issue as well, where the server response to a list request (so I'm naturally using Now, I do agree with @evictor's comment that this type of meta data should really be in response headers instead of the response body. But we don't always own the server, and cannot always make sure that responses follow good practices. Perhaps a solution like this would be acceptable (in the function handling the response, in the if (action.isArray) {
if (!isArray(data)) {
var accessor = /* ...some way to get a configurable accessor()... */ || 'objects';
data = isFunction(accessor) ? accessor(data) : data[accessor];
}
//...
} (Now, my apologies if a solution like this—which deals with others' bad practices—is against Angular's design philosophy.) |
Sill having this problem, but actually when executing POSTs (Angular v1.0.4) e.g. - In the Service:
In the controller:
Where 'outlineGroupings' is an array of objects. This all results in: TypeError: Object # has no method 'push' The request doesn't event hit the server, so I don't think it's a response issue in my case. |
@joforiam, your server probably isn't understanding AngularJS's |
I am seeing this issue with angular 1.0.5 with a ".get" call that returns an object which has an array as one of its properties. |
seems like angular.copy gets into this part of the code where destination is not an array.
|
I'm going to try running with this for a while diff --git public/js/angular.js public/js/angular.js
index 68b33c7..c201241 100644
--- public/js/angular.js
+++ public/js/angular.js
@@ -571,7 +571,7 @@ function copy(source, destination){
}
} else {
if (source === destination) throw Error("Can't copy equivalent objects or arrays");
- if (isArray(source)) {
+ if (isArray(source) && isArray(destination)) {
destination.length = 0;
for ( var i = 0; i < source.length; i++) {
destination.push(copy(source[i])); |
I'm having this issue also with AngularJS 1.0.5. My REST method returns following JSON response [
[
"=", "<=", "<", ">=", "<>"
],
null
] Error message
I'm using query(). |
Getting this issue when using .query() with array return. |
I am having no issues with the patch posted above and don't see this error any more. |
@joelwreed your patch fixes the problem on my side too. I'm gonna try to use another resource with |
@joelwreed your patch fixes my problem to. I hope this gets into angular.js soon. Thanks a lot!!! |
@joelwreed you should create a pull request with that patch. Seems like everybody runs into this at some point |
+1 Thanks. |
Waiting for this... |
This is not a bug in
or
See this example: http://jsfiddle.net/97Uqb/ I haven't seen any examples that are configured correctly and still throw this exception.
Can you post it so that we can check? The only other thing that could/should be done is to make the error message in $resource more clear. In other words, if you have a resource path that expects an array and gets an object (or vice versa) we throw a suitable error that explains this explicitly, rather than letting it fall through to |
When using $resource you must setup your actions carefully based on what the server returns. If the server responds to a request with an array then you must configure the action with `isArray:true` and vice versa. The built-in `get` action defaults to `isArray:false` and the `query` action defaults to `isArray:true`, which is must be changed if the server does not do this. Before the error message was an exception inside angular.copy, which didn't explain what the real problem was. Rather than changing the way that angular.copy works, this change ensures that a better error message is provided to the programmer if they do not set up their resource actions correctly. Closes angular#2255, angular#1044
When using $resource you must setup your actions carefully based on what the server returns. If the server responds to a request with an array then you must configure the action with `isArray:true` and vice versa. The built-in `get` action defaults to `isArray:false` and the `query` action defaults to `isArray:true`, which is must be changed if the server does not do this. Before the error message was an exception inside angular.copy, which didn't explain what the real problem was. Rather than changing the way that angular.copy works, this change ensures that a better error message is provided to the programmer if they do not set up their resource actions correctly. Closes angular#2255, angular#1044
When using $resource you must setup your actions carefully based on what the server returns. If the server responds to a request with an array then you must configure the action with `isArray:true` and vice versa. The built-in `get` action defaults to `isArray:false` and the `query` action defaults to `isArray:true`, which is must be changed if the server does not do this. Before the error message was an exception inside angular.copy, which didn't explain what the real problem was. Rather than changing the way that angular.copy works, this change ensures that a better error message is provided to the programmer if they do not set up their resource actions correctly. Closes angular#2255, angular#1044
When using $resource you must setup your actions carefully based on what the server returns. If the server responds to a request with an array then you must configure the action with `isArray:true` and vice versa. The built-in `get` action defaults to `isArray:false` and the `query` action defaults to `isArray:true`, which is must be changed if the server does not do this. Before the error message was an exception inside angular.copy, which didn't explain what the real problem was. Rather than changing the way that angular.copy works, this change ensures that a better error message is provided to the programmer if they do not set up their resource actions correctly. Closes #2255, #1044
I seem to be getting this despite having configured isArray. My configuration is: DataApp.factory('librarySkillsService', function enrollment($resource){
return $resource(root_url() + 'library_skill_categories/:id', { id: '@id' }, {
query: { method: 'GET', isArray: true }
});
}); My service returns an array of objects each having a property which is an array. Would nested arrays cause this kind of issue? |
try my fix alan, does it fix the problem for you? jr On 08/08/2013 09:19 PM, alanheppenstall wrote:
|
Hi Jr, No that doesn't seem to work. I still get the Object has no method 'push' error. |
When using resource on an endpoint which returns json objects of the form:
The resource class throws an error:
TypeError: Object #<Resource> has no method 'push'
at copy (http://code.angularjs.org/angular-1.0.0rc8.js:557:21)
at new Resource (http://code.angularjs.org/angular-resource-1.0.0rc8.js:323:9)
at http://code.angularjs.org/angular-resource-1.0.0rc8.js:379:32
at forEach (http://code.angularjs.org/angular-1.0.0rc8.js:118:20)
at http://code.angularjs.org/angular-resource-1.0.0rc8.js:378:19
at http://code.angularjs.org/angular-1.0.0rc8.js:6349:59
at http://code.angularjs.org/angular-1.0.0rc8.js:6386:26
at Object.$eval (http://code.angularjs.org/angular-1.0.0rc8.js:7444:28)
at Object.$digest (http://code.angularjs.org/angular-1.0.0rc8.js:7316:25)
at Object.$apply (http://code.angularjs.org/angular-1.0.0rc8.js:7527:22)
This is due to the Resource class not taking into consideration that part of the json can be an array. It assumes that the destination for copy is already an array when in reality its a Resource and then the push call fails.
The text was updated successfully, but these errors were encountered: