Skip to content

Commit 053a0da

Browse files
petebacondarwinksheedlo
authored andcommitted
fix(resource): check whether response matches action.isArray
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
1 parent b99d064 commit 053a0da

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

src/ngResource/resource.js

+4
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,10 @@ angular.module('ngResource', ['ng']).
473473
promise = value.$promise;
474474

475475
if (data) {
476+
if ( angular.isArray(data) != !!action.isArray ) {
477+
return $q.reject("Error in resource configuration. Expected response to contain an " +
478+
(action.isArray?'array':'object') + " but got an " + (angular.isArray(data)?'array':'object'));
479+
}
476480
if (action.isArray) {
477481
value.length = 0;
478482
forEach(data, function(item) {

test/ngResource/resourceSpec.js

+21
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,27 @@ describe("resource", function() {
807807
});
808808
});
809809

810+
it('should fail if action expects an object but response is an array', function() {
811+
var successHandler = jasmine.createSpy('successHandler');
812+
var failureHandler = jasmine.createSpy('failureHandler');
813+
$httpBackend.expect('GET', '/Customer/123').respond({id: 'abc'});
814+
$resource('/Customer/123').query().$promise.then(successHandler, failureHandler);
815+
$httpBackend.flush();
816+
expect(successHandler).not.toHaveBeenCalled();
817+
expect(failureHandler).toHaveBeenCalledWith(
818+
'Error in resource configuration. Expected response to contain an array but got an object');
819+
});
820+
821+
it('should fail if action expects an array but response is an object', function() {
822+
var successHandler = jasmine.createSpy('successHandler');
823+
var failureHandler = jasmine.createSpy('failureHandler');
824+
$httpBackend.expect('GET', '/Customer/123').respond([1,2,3]);
825+
$resource('/Customer/123').get().$promise.then(successHandler, failureHandler);
826+
$httpBackend.flush();
827+
expect(successHandler).not.toHaveBeenCalled();
828+
expect(failureHandler).toHaveBeenCalledWith(
829+
'Error in resource configuration. Expected response to contain an object but got an array');
830+
});
810831

811832
it('should transform request/response', function() {
812833
var Person = $resource('/Person/:id', {}, {

0 commit comments

Comments
 (0)