2

All,

i am trying to setup a global httpInterceptor to have a custom popup message when a client timeout appears, not a server one. I found this article: Angular $http : setting a promise on the 'timeout' config , and converted it into a httpInterceptor, but it does not work as expected and has some weird behavior.

 $provide.factory('timeoutHttpInterceptor', function ($q, $translate, $injector) {

        var timeout = $q.defer();

        var timedOut = false;

        setTimeout(function () {
            timedOut = true;
            timeout.resolve();
        }, 10000);
        return {
            request: function (config) {
                config.timeout = timeout.promise;
                return config;
            },
            response: function(response) {
                return response;
            },
            responseError: function (config) {
                if(timedOut) {
                    var toastr = $injector.get('toastr');
                    toastr.custom('network', $translate('title'), $translate('label'), { timeOut: 5000000000000, closeButton: true, closeHtml: '<button></button>' });
                    return $q.reject({
                        error: 'timeout',
                        message: 'Request took longer than 1 second(s).'
                    });
                }
            },
        };
    });

1 Answer 1

4

You can use $timeout service that returns a promise and assign it to config.timeout. Take a look at the code below.

.factory('timeoutInterceptor', ['$q','$timeout', function($q,$timeout) {
    return {
      request: function(config) {
        //assign a promise with a timeout, and set timedOut flag, no need to trigger $digest, thus false as 3rd param
        config.timeout = $timeout(function(){ config.timedOut = true },2000,false);
        return config;
      },
      responseError :function(rejection) {
        if(rejection.config.timedOut){ //if rejected because of the timeout - show a popup 
            alert('Request took longer than 1 second(s).');
        }
        return $q.reject(rejection);
      }
    };

Here is full working example : http://jsfiddle.net/2g1y4bk9/

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot for your answer, I implemented it and it works, very useful and super handy jsFiddle. I was looking for that a long time, but could not find the exact implementation for the httpInterceptor, so now other people hopefully can.
After implementing this we found some issues when using Selenium based Protractor tests. We also needed to release the object to make those tests work again. Related issue about protractor: stackoverflow.com/questions/26299173/… add this: response: function(response) { $timeout.cancel(response.config.timeout); return response; },

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.