Cancel / Abort all pending requests in angularJs

When changing the route, I need to cancel ALL pending requests from the previous route, so that I do not encounter problems with answers from the previous route, collecting data on my current route (sometimes this happens when the answers from the previous route take a long time to complete).

I thought about using http interceptor for this:

$httpProvider.interceptors.push(function($q) { return { 'request': function(config) { }, 'response': function(response) { } }; }); 

In the request function, I could change config.timeout with the promise suggested here and save all pending objects in the global cache so that I can cancel all of them.

The problem with this approach is that it can override config.timeout elsewhere in the code.

I think another solution might be to cancel all ajax requests at the XMLHttpRequest level, but I don't know how to do this.

Any suggestions? Thanks.

+7
javascript angularjs
source share
1 answer

As you say, timeout is the only API we use now to cancel a running $ http request. I think you are right for the money with an interceptor combined with a promise to cancel.

What you can do is attach the complete pending object in the $http request and cancel all pendingRequests in your route change handler.

Could something like this (possibly *) work?

 angular.module('module').config(function ($httpProvider) { $httpProvider.interceptors.push(function ($q) { return { request: function (config) { if (!config.timeout) { config.cancel = $q.defer(); config.timeout = config.cancel.promise; } return config; } } }); }); angular.module('module').run(function ($rootScope, $http) { $rootScope.$on('$stateChangeStart', function () { $http.pendingRequests.forEach(function (pendingReq) { if (pendingReq.cancel) { pendingReq.cancel.resolve('Cancel!'); } }); }); }); 

*: I say, maybe because I had success in this approach, but rarely do you find a silver bullet in something like that.


change

If you need to bypass the error handler of a canceled promise, connect to the responseError property and do manual labor.

 angular.module('module').config(function ($httpProvider) { $httpProvider.interceptors.push(function ($q) { return { responseError: function (response) { if (response.config.timeout.$$state.value === 'Cancel!') { // debugger; return $q.when('bypassed'); } } } }); }); 

I am starting to think that there is no general / “cool” solution to achieve the final result that you desire. Stepping on some strange ground here :)


edit2:

Testing above yourself now. Returning $q.when('something') to responseError will effectively bypass the error callback of the canceled $http request. Let me know if this works for you.

+6
source share

All Articles