Search code examples
angularjshttpxmlhttprequestinterceptorabort

Abort/cancel/abandon a http request in angular js and retry it again


I am working on an application in which i have to stop listening to a request if certain time is passed like if there is no response from a request in 60 secs then i have to abort that request and also there are multiple requests are going at a time. I don't know know how to keep track of each request with abort time(60 secs). I mean how would i know which request is to abort.

I want to implement this functionality in my AngularJS interceptor. I have tried many blogs and post that claims to achieve this functionality but nothing helps me

here is my interceptor code

    $httpProvider.interceptors.push(['$cookies', '$rootScope', '$q', '$localStorage', '$sessionStorage','$timeout', function ($cookies, $rootScope, $q, $localStorage, $sessionStorage, $timeout) {
        return {
            'request': function (config) {
                config.headers = config.headers || {};
                if (typeof config.data !== 'object') {
                    config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
                }
                config.headers.Accept = 'application/json;odata=verbose';
                config.headers['X-Requested-With'] = 'XMLHttpRequest';
                var token = $localStorage.authToken || $sessionStorage.authToken;                    
                if (token) {
                    config.headers.Authorization = 'Bearer ' + token;
                }

                return config;
            },
            'responseError': function (response) {
                var status = response.status;
                var error = '';
                if(response.data.error) {
                    error = response.data.error;
                }
                if(status === 401) {
                    $rootScope.unauthorizedLogout();
                } else if(status === 400 && (error === 'token_invalid' || error === 'token_not_provided')) {
                    $rootScope.unauthorizedLogout();
                } 
                return $q.reject(response);
            }
        };
    }]); 

I do tried the $q.defer and it's resolve method to cancel request but it's not helping me to achieve the functionality i want in application.

Peace out V


Solution

  • This answer helped me a lot

    set incremented timeout value to request

        config.timeout = incrementalTimeout;
    

    Your interceptor for handling response error should look like this

       'responseError': function (response) {
        var status = response.status;
        var error = '';
        //functionality to for request aborting and resending
        if (status === -1 || status >= 500) {
            if (attempts <= 3) {
                attempts += 1;
                return retryRequest(response.config);
            }
        } else {
            // set incrementalTiemout and attempts to default value   
            incrementalTimeout = 4000;
            attempts = 1;
        }
        if(response.data.error) {
            error = response.data.error;
        }
        if(status === 401) {
            $rootScope.unauthorizedLogout();
        } else if(status === 400 && (error === 'token_invalid' || error === 'token_not_provided')) {
            $rootScope.unauthorizedLogout();
        }
        return $q.reject(response);
    }
    

    code to resend request in your interceptor

            // default request timeout is of 4 seconds and attempt is 1
            var incrementalTimeout = 4000;
            var attempts = 1;
            function retryRequest (httpConfig) {
                var thisTimeout = incrementalTimeout;
                incrementalTimeout += 1000;
                return $timeout(function() {
                    var $http = $injector.get('$http');
                    return $http(httpConfig);
                }, thisTimeout);
            }