1

My code makes many AngularJS $http requests. Often it is 3-4 at the same time.

Is there some way that I can intercept the http messages so that I get just one alert pop up if the internet connectivity is lost and there are multiple requests going on? I have seen other sites that do this but then if the action requires a number of http calls it seems that I could get more than one error popup coming.

If possible I would like to do this in just the one place in my code.

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Alan2
  • 23,493
  • 79
  • 256
  • 450

2 Answers2

2

You need add responseInterceptors inside you $httpProvider in configuration phase of angular. This interceptor gets called after angular $httpProvider processing the response.

CODE

module.config(['$httpProvider', function($httpProvider) {
    var interceptor = ['$rootScope', '$q', '$location', function(scope, $q, $location) {
        function success(response) {
            return response;
        }

        function error(response) {
            var status = response.status;
            if (status == 500) {
                alert("Internal Server Error")
                return;
            }
            if (status == 404) {
                alert("Page not found")
                return;
            }
            // otherwise
            return $q.reject(responseInterceptors);

        }

        return function(promise) {
            return promise.then(success, error);
        }

    }];
    $httpProvider.responseInterceptors.push(interceptor);
}]);

Above code will provide you better control on error handling when any request fails.

For more details refer this anwser.

Update

For showing alert only once we could create a service,if error occurred then that will handle the set error variable

Service

module.service('errorService',function(){
   //getter
   this.getErrorFlag = function(){
     return this.isError;
   }
   //setter
   this.setErrorFlag = function(val){
     this.isError = val;
   }
});

Interceptor

module.config(['$httpProvider', function($httpProvider) {
    var interceptor = ['$rootScope', '$q', '$location','errorService', function(scope, $q, $location,errorService) {
        function success(response) {
            return response;
        }

        function error(response) {
            //setting error variable
            errorService.setErrorFlag(true)
            return $q.reject(responseInterceptors);
        }

        return function(promise) {
            return promise.then(success, error);
        }

    }];
    $httpProvider.responseInterceptors.push(interceptor);
}]);

Inside you controller put all $http call promises inside $q.all, and when promises gets resolved then check for isError flag of errorService. IsError flag will be true if error occurred at least one & by using it you can show error only once.

Controller

module.controller('appCtrl',['$scope','$q','errorService',function($scope,$q,errorService){
    var ajax1 = $http.get('url').then(function(){
    },
    function(){
    });
    var ajax2 = $http.get('url').then(function(){
    },
    function(){
    });
    var ajax3 = $http.get('url').then(function(){
    },
    function(){
    });
    errorService.setErrorFlag(false);
    $q.all(ajax1, ajax2, ajax3).then(function(data){
      //check for isError flag from service
      if(errorService.getErrorFlag())
        alert('Error occurred while processing request.'); //this will show only once
      else
        alert('No error occurred while processing request.')
    });
}]);

Hope this could help you. Thanks.

Community
  • 1
  • 1
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • Your solution looks like it's a good way but when my pages sometimes make many requests I think this will cause multiple alert boxes to come up. – Alan2 Feb 07 '15 at 12:01
  • @Alan Why you don't redirect user to error page..then there is no issue of handling multiple error using `window.location.hash="/error"` – Pankaj Parkar Feb 07 '15 at 12:18
  • @Alan check my code..I updated the answer. hopefully it will satisfy your requirement to show error only once.. – Pankaj Parkar Feb 08 '15 at 10:47
0

If you don't want to use an interceptor, you could simply process the error callback of your $http calls:

$scope.httpError = null;

$scope.processHttpError = function() {
  // If you don't already have got an http error
  if (!$scope.httpError) {
    $scope.httpError = "Cannot load stuff";
  }
};

$http.get('/someUrl')
  .success(function(data, status, headers, config) { ... })
  .error($scope.processHttpError);
floribon
  • 19,175
  • 5
  • 54
  • 66