Skip to content

Commit 37d1e5e

Browse files
author
Artemy Tregubenko
committed
feat(ngResource): Add $abort method to objects returned by $resource "class" actions
1 parent 0559652 commit 37d1e5e

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

src/ngResource/resource.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ function shallowClearAndCopy(src, dst) {
202202
* rejection), `false` before that. Knowing if the Resource has been resolved is useful in
203203
* data-binding.
204204
*
205+
* - `$abort`: a method to abort the request if it has not completed yet.
206+
*
205207
* @example
206208
*
207209
* # Credit card resource
@@ -303,7 +305,7 @@ function shallowClearAndCopy(src, dst) {
303305
* </pre>
304306
*/
305307
angular.module('ngResource', ['ng']).
306-
factory('$resource', ['$http', '$q', function($http, $q) {
308+
factory('$resource', ['$http', '$q', '$timeout', function($http, $q, $timeout) {
307309

308310
var DEFAULT_ACTIONS = {
309311
'get': {method:'GET'},
@@ -501,6 +503,16 @@ angular.module('ngResource', ['ng']).
501503
}
502504
});
503505

506+
// If parameters do not contain `timeout` which is a promise, create it,
507+
// so that later this call can be aborted by resolving this promise
508+
var timeout = httpConfig.timeout;
509+
if (!timeout || !timeout.then) {
510+
var timeoutDeferred = $q.defer();
511+
httpConfig.timeout = timeoutDeferred.promise;
512+
// If timeout is specified in milliseconds, use it to abort via promise
513+
if (timeout) $timeout(timeoutDeferred.resolve, timeout);
514+
}
515+
504516
if (hasBody) httpConfig.data = data;
505517
route.setUrlParams(httpConfig,
506518
extend({}, extractParams(data, action.params || {}), params),
@@ -557,6 +569,7 @@ angular.module('ngResource', ['ng']).
557569
// - return the instance / collection
558570
value.$promise = promise;
559571
value.$resolved = false;
572+
if (timeoutDeferred) value.$abort = timeoutDeferred.resolve;
560573

561574
return value;
562575
}

test/ngResource/resourceSpec.js

+32
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,22 @@ describe("resource", function() {
674674
});
675675

676676

677+
it('should add $abort method to the result object', function(){
678+
$httpBackend.expect('POST', '/CreditCard/123!charge?amount=10', '{"auth":"abc"}').respond({success: 'ok'});
679+
var errorCallback = jasmine.createSpy();
680+
var cc = CreditCard.charge({id:123, amount:10}, {auth:'abc'});
681+
cc.$promise.then(callback, errorCallback);
682+
683+
expect(cc.$abort).toEqual(jasmine.any(Function));
684+
cc.$abort();
685+
686+
$httpBackend.verifyNoOutstandingExpectation();
687+
$httpBackend.verifyNoOutstandingRequest();
688+
expect(callback).not.toHaveBeenCalled();
689+
expect(errorCallback).toHaveBeenCalled();
690+
});
691+
692+
677693
it('should return promise from action method calls', function() {
678694
$httpBackend.expect('GET', '/CreditCard/123').respond({id: 123, number: '9876'});
679695
var cc = new CreditCard({name: 'Mojo'});
@@ -837,6 +853,22 @@ describe("resource", function() {
837853
expect(callback).toHaveBeenCalledOnce();
838854
expect(ccs.$resolved).toBe(true);
839855
});
856+
857+
858+
it('should add $abort method to the result object', function(){
859+
$httpBackend.expect('GET', '/CreditCard?key=value').respond([{id: 1}, {id: 2}]);
860+
var errorCallback = jasmine.createSpy();
861+
var ccs = CreditCard.query({key: 'value'});
862+
ccs.$promise.then(callback, errorCallback);
863+
864+
expect(ccs.$abort).toEqual(jasmine.any(Function));
865+
ccs.$abort();
866+
867+
$httpBackend.verifyNoOutstandingExpectation();
868+
$httpBackend.verifyNoOutstandingRequest();
869+
expect(callback).not.toHaveBeenCalled();
870+
expect(errorCallback).toHaveBeenCalled();
871+
});
840872
});
841873

842874
it('should allow per action response interceptor that gets full response', function() {

0 commit comments

Comments
 (0)