What is Interceptor in Angular?
Angular Interceptor is a powerful feature that can be used in many ways for securing and handling many HTTP related phenomena. Interceptors provide a mechanism to intercept and/or mutate outgoing requests or incoming responses.
What is the use of Interceptors in Angular?
There is numerous use of interceptors in any Angular application. There are the following:-
- Setting request headers in HTTP Calls using interceptors.
- Authenticate HTTP calls by setting security tokens.
- Change the response from the HTTP service call before it is used by the code block.
- Use it for global error handling in your application.
- Showing global spin loader or progress bar for each HTTP call.
Creating HTTP Interceptors in Angular
Now let’s learn various HTTP interceptor examples. We are going to learn different use-cases of interceptors in an angular app.
To implement an interceptor, you’ll want to create a class that’s injectable and that implements HttpInterceptor
. The class should define an intercept
method to correctly implement HttpInterceptor. The intercept method takes two arguments, req
and next
, and returns an observable of type HttpEvent
.
req
is the request object itself and is of typeHttpRequest
.next
is the HTTP handler, of typeHttpHandler
. The handler has a handle method that returns our desired HttpEvent observable.
1. Add Request Header using Interceptors
In this example, we will learn how to change the HTTP request header using the interceptor. Let’s create a new interceptor customheaderInterceptor
class in our project.
|
|
Once you create interceptor class, import these dependencies in the same class file.
Put @Injectable()
directive on customheaderInterceptor
class. Now implement the class with HttpInterceptor
. VS Code editor will a warning message to implement the HttpInterceptor
. Click on the message and it will add an intercept
method inside the class.
Here is the code.
|
|
HttpRequest: It is an outgoing HTTP request. It provides getters to fetch request properties such as method
, urlWithParams
etc.
HttpHandler: It transforms an HttpRequest
into a stream of HttpEvent
. HttpHandler
provides handle()
method to dispatch request from first interceptor to second and so on.
HttpResponse: It is a full HTTP response. It has getter methods such as body
, headers
, status
, url
etc.
Configure HTTP Interceptors in AppModule
To use the same instance of HttpInterceptors
for the entire app, import the HttpClientModule only in your AppModule
, and add the interceptors to the root application injector. If you import HttpClientModule multiple times across different modules (for example, in lazy loading modules), each import creates a new copy of the HttpClientModule, which overwrites the interceptors provided in the root module.
Interceptors are configured in AppModule like below.
|
|
If there are multiple interceptors, you can create a constant and configure them in this constant.
|
|
Let’s see how to declare HTTP Interceptors in our AppModule
file.
Import HTTP_INTERCEPTORS
and CustomHeaderInterceptor
in app.module.ts
file. After importing, make an entry of HTTP_INTERCEPTORS in NgModule’s providers[]
array.
|
|
Now, in order to change the HTTP request header, we need a mock service. Here, I am going to use an online mock service website mocky.io.
Here we got our service endpoint once you click on Generate my HTTP Response
button.
http://www.mocky.io/v2/5e4605113300006700025eab
Let’s add a custom header in request via the interceptor.
|
|
In this above code, we have added one header named custom-header
and set its value to zeptobook
. Now, for every ongoing HTTP request from our application, this custom-header will be appended in request headers.
Here is the complete code of our interceptor for changing the request header.
|
|
Finally, here is our HTTP call to mock service. This service call will have our custom header in the request header and it will return an HTTP response.
|
|
Now you can verify your service request in the browser’s console window.
Here is the service response.
2. Cross-Site Request Forgery (XSRF or CSRF) protection by Interceptors
HTTP interceptors provide security from Cross-Site Request Forgery (XSRF or CSRF) by reading a token from cookie by, default XSRF-TOKEN
, and sets it as an HTTP header, X-XSRF-TOKEN
.
By default, an interceptor sends this cookie on all mutating requests i.e. POST, PUT, DELETE etc. to relative URLs but NOT on GET / HEAD requests (since they are read-only) or on requests with an absolute URL (since it is a different domain altogether).
To take advantage of this, the server needs to set a token in a JS readable session cookie called XSRF-TOKEN
on either the page load or the first GET request.
On subsequent requests, the server can verify that the cookie matches the X-XSRF-TOKEN
HTTP header and thus, be sure that only code running on your domain has sent this request.
3. Global Error Handling using Interceptors
Using the interceptor, you can handle global errors that can happen across your application. Interceptors are the centralized system that takes care of your all HTTP requests and responses.
Since every request you’re making goes trough this interceptor, we can also use this interceptor to catch all requests that return as an instance of HttpErrorResponse
. This is how you do that:
We send the request to the HttpHandler
and then execute the request. In the callback function we check for errors. If the error is an instance of HttpErrorResponse
we can send the request to an error handler that displays a nice little message with what went wrong.
In the below code, I changed my interceptor to catch an HTTP error for the wrong service URL. I have intentionally changed the service URL to the wrong URL and try to catch the error.
|
|
I have put mocky.io
to mocky1.io
in my get()
call in app.component.ts
http://www.mocky1.io/v2/5e4605113300006700025eab
|
|
It will show an error alert on page load.
4. Using Angular Interceptors for Logging or Profiling
You can use the Angular interceptor for application logging purposes. We are now going to create a logger to show exactly which method is being called, the data being sent, headers and everything you need, there is no risk of mistaking one server interaction with another one.
The implementation below also includes a fix for GET calls using Internet Explorer, which sometimes seems to do some undesirable caching. By having this somewhat dirty code in an HTTP interceptor, we can at least keep it in one place and not have to think about it for every new HTTP GET call we add.
|
|
This logging interceptor now logs each GET request in the browser window.
5. Mock Backend Using Angular Interceptors
There are times when we have to work fastly but server-side backend APIs are not ready to work. So, Angular provides you a facility to create your own mock backend service using the interceptor. It is very easy to create your own fake response data using the interceptor.
Let’s see how to create a mock backend using the interceptor.
|
|
In the above code, we have created a mockData
constant. From lines 26-28, we are checking the url and returning this mockData
as an service response with a status code of 200.
In our app.component.ts file, we are calling our mock data service.
|
|
Here is our response data from the mock backend service.
6. Change Url by Interceptors
You can’t directly change HTTPRequest
and HTTPResponse
instance properties, because they are readonly
and immutable.
Since these are read-only
, you can’t change url by using any string function like replace.
To alter the request, clone it first and modify the clone before passing it to next.handle()
. You can clone and modify the request in a single step as in this example.
|
|
Summary
Interceptors were a great addition in Angular 4.3 and had many excellent use cases as we have seen here. As we’ve seen in these examples, interceptors provide a straightforward mechanism to interact with HTTP requests and responses. This makes it easy to add layers of control and provide more functionality throughout an application without duplicating logic.
Further Reading
Understanding Angular Modules and Its Types
How Change Detection Works In Angular