Using $httpInterceptor for request/response handling

Loading

In AngularJS, $httpInterceptor is a powerful mechanism to intercept HTTP requests and responses globally. This helps in adding headers, logging, modifying responses, handling errors, and implementing authentication logic without modifying every $http request.


1. What is $httpInterceptor?

  • It is a factory that allows us to intercept every HTTP request and response.
  • We can modify them before they are sent or processed.
  • It is added using $httpProvider.interceptors.push().

2. Creating an $httpInterceptor

We define an interceptor as a factory service and push it to $httpProvider.

Basic Structure of $httpInterceptor

myApp.factory('ApiInterceptor', function($q, $rootScope, $injector) {
return {
// Intercept the request before sending
request: function(config) {
console.log('Outgoing request:', config);
return config;
},

// Handle request errors
requestError: function(rejection) {
console.error('Request error:', rejection);
return $q.reject(rejection);
},

// Intercept the response before passing it to the caller
response: function(response) {
console.log('Incoming response:', response);
return response;
},

// Handle response errors
responseError: function(response) {
console.error('Response error:', response);
return $q.reject(response);
}
};
});

// Add interceptor to $httpProvider
myApp.config(function($httpProvider) {
$httpProvider.interceptors.push('ApiInterceptor');
});

Key Points:
request → Modify or log request before it is sent.
requestError → Handle request failures (e.g., network issues).
response → Modify or log the response before it reaches the caller.
responseError → Handle errors globally (e.g., 401 Unauthorized, 500 Server Error).


3. Adding Authentication Token to Requests

A common use case is adding a JWT token or API key in headers for authentication.

myApp.factory('AuthInterceptor', function($q, $injector) {
return {
request: function(config) {
var token = localStorage.getItem('authToken'); // Get stored token
if (token) {
config.headers.Authorization = 'Bearer ' + token;
}
return config;
},

responseError: function(response) {
if (response.status === 401) {
console.warn('Unauthorized! Redirecting to login...');
var $state = $injector.get('$state');
$state.go('login'); // Redirect user to login page
}
return $q.reject(response);
}
};
});

// Register the interceptor
myApp.config(function($httpProvider) {
$httpProvider.interceptors.push('AuthInterceptor');
});

Benefits:
✔ Automatically attaches tokens to every request.
✔ Redirects unauthenticated users to the login page.


4. Handling API Errors Globally

Instead of handling errors in every $http call, use an interceptor.

myApp.factory('ErrorInterceptor', function($q, $rootScope) {
return {
responseError: function(response) {
switch (response.status) {
case 400:
alert("Bad Request: " + response.data.message);
break;
case 401:
$rootScope.$broadcast('unauthorized');
break;
case 403:
alert("Forbidden: You don't have permission!");
break;
case 404:
alert("Not Found: The requested resource doesn't exist.");
break;
case 500:
alert("Server Error: Please try again later.");
break;
}
return $q.reject(response);
}
};
});

// Register the interceptor
myApp.config(function($httpProvider) {
$httpProvider.interceptors.push('ErrorInterceptor');
});

Advantages:
✔ Centralized error handling for all API requests.
✔ Avoids duplicate error handling in controllers.


5. Logging API Requests & Responses

For debugging, log every request and response.

myApp.factory('LoggerInterceptor', function() {
return {
request: function(config) {
console.log('Request:', config.method, config.url);
return config;
},
response: function(response) {
console.log('Response:', response.status, response.config.url);
return response;
}
};
});

myApp.config(function($httpProvider) {
$httpProvider.interceptors.push('LoggerInterceptor');
});

Advantages:
✔ Helps in debugging API issues.
✔ Logs every request and response.


6. Implementing Retry Logic for API Calls

If an API call fails, retry it a few times before failing completely.

myApp.factory('RetryInterceptor', function($q, $injector) {
return {
responseError: function(response) {
var retries = response.config.retries || 3; // Default 3 retries

if (retries > 0) {
console.log(`Retrying ${response.config.url}, attempts left: ${retries - 1}`);

var $http = $injector.get('$http');
response.config.retries = retries - 1;
return $http(response.config);
}

return $q.reject(response);
}
};
});

// Register the interceptor
myApp.config(function($httpProvider) {
$httpProvider.interceptors.push('RetryInterceptor');
});

Benefits:
✔ Retries failed API calls automatically.
✔ Reduces network failure impact.


7. Combining Multiple Interceptors

We can use multiple interceptors together:

myApp.config(function($httpProvider) {
$httpProvider.interceptors.push('AuthInterceptor');
$httpProvider.interceptors.push('ErrorInterceptor');
$httpProvider.interceptors.push('LoggerInterceptor');
});

Leave a Reply

Your email address will not be published. Required fields are marked *