diff --git a/src/module/api/common-api.js b/src/module/api/common-api.js index aedaf54..cf89074 100644 --- a/src/module/api/common-api.js +++ b/src/module/api/common-api.js @@ -381,6 +381,14 @@ RMModule.factory('RMCommonApi', ['$http', 'RMFastQ', '$log', 'RMUtils', function return this.$always(function() { + var defaultOptions = {}; + + if(action && action.aborter) { + defaultOptions.timeout = action.aborter.promise; + } + + _options = angular.extend(defaultOptions, _options); + this.$response = null; this.$status = 'pending'; this.$dispatch('before-request', [_options]); @@ -431,7 +439,8 @@ RMModule.factory('RMCommonApi', ['$http', 'RMFastQ', '$log', 'RMUtils', function */ $action: function(_fun) { var status = { - canceled: false + canceled: false, + aborter: $q.defer() }, pending = this.$pending || (this.$pending = []); pending.push(status); @@ -473,6 +482,24 @@ RMModule.factory('RMCommonApi', ['$http', 'RMFastQ', '$log', 'RMUtils', function return this; }, + /** + * @memberof CommonApi# + * + * @description Aborts all pending actions registered with $action. + * + * @return {CommonApi} self + */ + $abort: function() { + // abort every pending request. + if(this.$pending) { + angular.forEach(this.$pending, function(_status) { + _status.aborter.resolve(); + }); + } + + return this; + }, + /** * @memberof CommonApi# * @@ -495,4 +522,4 @@ RMModule.factory('RMCommonApi', ['$http', 'RMFastQ', '$log', 'RMUtils', function return CommonApi; -}]); \ No newline at end of file +}]); diff --git a/src/module/fastq.js b/src/module/fastq.js index 53429a6..343b951 100644 --- a/src/module/fastq.js +++ b/src/module/fastq.js @@ -8,7 +8,7 @@ * Synchronous promise implementation (partial) * */ -RMModule.factory('RMFastQ', [function() { +RMModule.factory('RMFastQ', ['$q', function($q) { var isFunction = angular.isFunction, catchError = function(_error) { @@ -78,6 +78,8 @@ RMModule.factory('RMFastQ', [function() { return simpleQ(_val, false); }, - wrap: wrappedQ + wrap: wrappedQ, + + defer: $q.defer }; }]); diff --git a/test/common-api-spec.js b/test/common-api-spec.js index d810435..022df2c 100644 --- a/test/common-api-spec.js +++ b/test/common-api-spec.js @@ -135,6 +135,33 @@ describe('Restmod model class:', function() { }); }); + describe('$abort', function() { + it('should abort every pending action', function() { + var bike = Bike.$new(), + spy = jasmine.createSpy('done'); + + $httpBackend.expect('GET', '/api/bikes/1').respond(200); + + bike.$action(function() { + this.$send({ url: '/api/bikes/1', method: 'GET' }).$asPromise().catch(function(response) { + var response = response.$response; + expect(response.data).toBeUndefined(); + expect(response.status).toBe(-1); + expect(response.config.url).toBe('/api/bikes/1'); + spy(); + }); + }); + + $rootScope.$apply(function() { + bike.$abort(); + }); + + expect(spy).toHaveBeenCalled(); + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + }); + describe('$action', function() { it('should keep action in pending action list until its done', function() {