Melkor
Melkor

Reputation: 532

In AngularJS, how can I apply a check function on all the responses of `$http`?

$http({
    method: 'POST',
    url: '/getAllUsers'
}).success(function(data, status, headers, config) {
    if (data.length === 0) {
        $location.path('/admin/login');
    }
    // process data
    if (data.ok == 1) {
        // correct data
    } else {
        // error
    }
})

I use $http to fetch server data, and the server will respond an empty string if the auth fails. What I want to do is, if data is empty, then the application should redirect to login page. But since there are many controllers, and each controller has several $http call, so I don't want to copy and paste the directing code everywhere.

Is there any way I can "inject" this function on every $http response without writing the same code everywhere?

And am I able to apply it only on $http calls in some specific controllers?

Upvotes: 1

Views: 108

Answers (3)

Asik
Asik

Reputation: 7977

You can create a factory definition and push it in config phase as Interceptor (using $httpprovider)

Factory Definition

angular.module('myApp').factory('httpInterceptor', ['$location', function($location) {
    var httpInterceptor = {
        response: function(config){ 
            if (config.data.trim() == "") {
                $location.path('\login');
            }

            return config;
        }
    };
    return httpInterceptor;
}]);

Config Phase

angular.module('myApp').config(['$httpProvider' ,function($httpProvider) {
   $httpProvider.interceptors.push('httpInterceptor');
}]);

Upvotes: 1

hansmaad
hansmaad

Reputation: 18905

You can use a http intercetor. The intercetor's response method is called right after $http receives the response from the backend. You can modify the response or make other actions. The method get called with the http response object and needs to return the response object directly, or as a promise containing the response or a new response object.

$provide.factory('myHttpInterceptor', function() {
  return {
    'response': function(response) {
       if (/* response failed */ ) {
          // $rootScope broadcast
          // or $location login
          // or whatever you want
       }

       return response;
     }
   };
});

$httpProvider.interceptors.push('myHttpInterceptor');

Edit: I'm not sure if this is correct usage of $http config (I'never done this..) but you could also conditionally add a transformResponse function to a single $http call like this:

function transformErrorResponse(data, headersGetter, status) {
  if (/* failed */)
    // handle failure
}

$http({ transformResponse : transformErrorResponse})
  .get(/*  */)
  .then(/*  */);

Upvotes: 3

Aditya
Aditya

Reputation: 196

You can write a simple config for $http in your module config and write your error handling in the transformResponse property of the $http config. Something like this:

angular.module("yourModule", []).config ($http) ->
     $http({

        transformResponse:(data, headersGetter, status)->
             /**Handle your data empty stuff here. ***/

      })

Upvotes: 0

Related Questions