Canceling a request using the $ http interceptor?

I am trying to figure out if the $http interceptor can be used to cancel the request before it occurs.

There is a button that launches the request, but if the user double-clicks it, I do not want the same request to be turned on twice.

Now I understand that there are several ways to solve this problem, and we already have a working solution where we wrap $http in a service that tracks requests that are currently pending and simply ignores new requests using the same method URL and data.

This is basically the behavior that I'm trying to do with an interceptor:

 factory('httpService', ['$http', function($http) { var pendingCalls = {}; var createKey = function(url, data, method) { return method + url + JSON.stringify(data); }; var send = function(url, data, method) { var key = createKey(url, data, method); if (pendingCalls[key]) { return pendingCalls[key]; } var promise = $http({ method: method, url: url, data: data }); pendingCalls[key] = promise; promise.finally(function() { delete pendingCalls[key]; }); return promise; }; return { post: function(url, data) { return send(url, data, 'POST'); } } }]) 

When I look at the $http interceptor API, this is not like achieving this. I have access to the config object, but more on that.

Am I trying to go beyond what interceptors can be used here or is there a way to do this?

+10
angularjs
Feb 28 '14 at 9:13
source share
2 answers

according to the $ http documentation , you can return your own configuration from an interceptor request.

try something like this:

 config(function($httpProvider) { var cache = {}; $httpProvider.interceptors.push(function() { return { response : function(config) { var key = createKey(config); var cached = cache[key]; return cached ? cached : cached[key]; } } }); } 
+1
Aug 07 '14 at 6:02
source

A very old question, but I will take a picture to deal with this situation.

If I understood correctly, you are trying:

1 - Run the request and register something to return to it;

2 - If another request is made to the same endpoint, you want to get this first link and drop the request in it.

This may be due to the request timeout in the configuration object $http . On the interceptor, you can check it there, registered in the current request, if not, you can install it, save a link to it and process it if, subsequently:

 function DropoutInterceptor($injector) { var $q = $q || $injector.get('$q'); var dropouts = {}; return { 'request': function(config) { // I'm using the request URL here to make // this reference, but this can be bad for // some situations. if (dropouts.hasOwnProperty(config.url)) { // Drop the request dropouts[config.url].resolve(); } dropouts[config.url] = $q.defer(); // If the request already have one timeout // defined, keep it, othwerwise, set up ours. config.timeout = config.timeout || dropouts[config.url]; return config; }, 'requestError': function(reason) { delete dropouts[reason.config.url]; return $q.reject(reason); }, 'response': function(response) { delete dropouts[response.config.url]; return response; }, 'responseError': function(reason) { delete dropouts[reason.config.url]; return $q.reject(reason); } }; } 
+1
Jan 16 '17 at 22:21
source



All Articles