Use Angular $http Interceptors
When working with HTTP API of an backend, you need to handle various response from those APIs and make your own reaction on either success or failure response.
But those APIs are not always designed RESTfully, It may not indicate an error status using the status code of HTTP. Instead, it may use an special field in the
response body to indicate a status of an response. This implicate an burden on the developer who will not be able to use the facility provided by the
framework like $http
. Normally, $http()
would return an promise object which can be chained with then
method to handle both success or failure response.
But when an HTTP request doesn’t using HTTP status code to indicate its result, your error handlers will never be called.
In this case, you may need to check the response entity carefully to see whether its special field indicates its failure status.
I’v also encountered this issue when joining a new team. And I think I can’t change the API definition. So the only way to save time is do some tricky. And this issue can be easily solved by using $http interceptors.
Assume that I have an API which return an object like this.
1 | { |
Well, this API definition is very straightforward though it is not follow the RESTful style. What I need do is to intercept every response made from this API
and check the value of status
. If it is not 0, change the statusCode of the response object to >=400. Besides, that I also want to make an global interceptor
to achieve this so I can get rid of writing same check code everywhere.
Let’s start to see what $http interceptors can help.
According to AngularJS Document Interceptors are factory which can modify request and response.
You need define some interceptors and push them into $httpProvider.interceptors
array in your config
function.
Let’s define an interceptor to check the status and reject the response if status code is not 0.
Assume we have an API pattern is /api/:someTarget
(:someTarget is an parameter which can be changed by need).
1 | var restInterceptor = angular.module('RestInterceptor', []); |
This code snippet create an interceptor to check the normal response whose HTTP status code is usually 200, but modify an response if its data.status doesn’t equal 0. and modify the HTTP status code to 400. so we can treat the API as an RESTful API and All the facility provided by angular or three party dependency can be used directly without redundant check code.
The rest job is to make the interceptor work, we need to push this factory into $httpProvider.interceptors
. Note that the invoke order of response
and responseError
interceptors are in reverse registration order. This is not clearly documented in official document.
1 | var app = angular.module('myApp', ['RestInterceptor']); |
Now you can write your code without need to check whether you got an error in your success handler.
1 | var app = angular.module('myApp'); |
Next time, I will use interceptor to write a notification module which will automatically make a toast notification to user when an API request has failed. And will combine with the RestInterceptor I just have wrote.