0

So I have a bunch of controllers that do $http requests

but in every $http request i have a .error(function(data...){//always the same})

How could I build an.. "abstract class" for $http?

This here would be the always repeating code

.error(function(){
    $scope.flashes = {
        server: {
            type: "danger",
            message: "There was a server error processing your request. Please try again later."
        }
    };
})

2 Answers 2

1

I add the same concern few weeks ago and i came up with this solution :

I first created a custom service intercepting every http requests made :

.factory('HttpInterceptor', ['$q', '$rootScope', function($q, $rootScope) {
return {
            // On request success
            request : function(config) {
                // Return the config or wrap it in a promise if blank.
                return config || $q.when(config);
            },

            // On request failure
            requestError : function(rejection) {
                //console.log(rejection); // Contains the data about the error on the request.  
                // Return the promise rejection.
                return $q.reject(rejection);
            },

            // On response success
            response : function(response) {
                //console.log(response); // Contains the data from the response.
                // Return the response or promise.
                return response || $q.when(response);
            },

            // On response failure
            responseError : function(rejection) {
                //console.log(rejection); // Contains the data about the error.
                //Check whether the intercept param is set in the config array. If the intercept param is missing or set to true, we display a modal containing the error
                if (rejection.config && typeof rejection.config.intercept === 'undefined' || rejection.config.intercept)
                {
                    //emitting an event to draw a modal using angular bootstrap
                    $rootScope.$emit('errorModal', rejection.data);
                }

                // Return the promise rejection.
                return $q.reject(rejection);
            }
        };
}]);

I also defined a custom config property 'intercept' that i can add to the $http config object. It is useful when I don't want to apply this behavior on a particular request. E.g :

var registerResource = $resource('/registration/candidate/register', {},    {query: 
                                                                        {method:'POST', isArray: false, intercept: false }
        });

In order the have a flexible solution, it is also important to not forget to do :

 return $q.reject(rejection);

So you can still use the error callback on your promise in your controller if you want to combine both ways (interception + manual handling)

Finally, I added this service to my application :

app.config(['$httpProvider', function($httpProvider) {
        // Add the interceptor to the $httpProvider to intercept http calls
        $httpProvider.interceptors.push('HttpInterceptor');

    }]);

I simplified the service but you can also use it for many things. Personally, I also use it to :

  • Make sure to not fire duplicate http requests (if the user click a lot on a submit button).

  • Draw an alert at the beginning of an http call and close it at the end to inform the user that is treatment is processing (export of data for instance).

PS: The official documentation mention this interceptor

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

Comments

0

You could do something like this:

app.service('myHttp', function($http){
  return function($scope, httpParameters){
    var httpPromise = $http(httpParameters);
    httpPromise.error(function(){
      $scope.flashes = {
         server: {
            type: "danger",
            message: "There was a server error"
         }
      }
    });
  };
});

app.controller('MainCtrl', function($scope, myHttp) {
   myHttp($scope, {method: 'GET', url: 'www.google.com'});
});

Comments