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!') {
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.
Kasper Lewau
source share