7.4 Intercepting Requests
In this lesson I'll show you how to create an HTTP interceptor which can be used to intercept any HTTP request made in the app. This lets you modify the requests or responses on the fly.
1.Introduction6 lessons, 42:00
2.Get Started With Angular7 lessons, 42:38
3.Core Concepts7 lessons, 55:20
4.Template Deep Dive11 lessons, 1:10:56
5.Forms10 lessons, 1:45:41
6.Routing9 lessons, 1:15:10
7.Using the HTTP Client5 lessons, 56:24
8.Testing10 lessons, 1:23:27
9.Building for Production1 lesson, 03:40
10.Conclusion1 lesson, 01:32
7.4 Intercepting Requests
Hi folks. In this lesson, we're gonna take a look at how we can intercept any HTTP requests that are made anywhere in our application, so that we can inspect and perhaps even modify the request or response. HTTP interceptors follow the same middleware pattern that is used in common Node frameworks like Express.js. Well, we can have a chain of interceptors, and any request will be passed through each of them with each interceptor in the chain doing something with the request and then passing it along to the next interceptor. In last lesson, we added the x-requested-with header to the request to the numbers API. This is the only request that we'll be making in the application. But just imagine that we were making lots and lots of requests from many different places within the application. If we wanted to set this header on all of our requests, we have two options really. We can find and modify every single HTTP request all over the application and set the header manually in all of them, resulting in lots of duplicate code throughout the application. Or we could use a single interceptor which modifies any request from the app and sets the header. Then we only have one instance of the header setting code. I know which I'd prefer to do. So let's make use of an HTTP interceptor to set our header. An interceptor is basically a service, but we can't use the CLI to automatically generate one for us. So let's just create a new typescript file in our _services folder. We'll call this one requested-with-header.interceptor.ts. So we're keeping with the usual Angular naming convention for our file, and that consists of a name which indicates what the file is for followed by a dot followed by the type of thing that it is, in this case an interceptor. So we can import the injectable decorator as befits an Angular service. There's also a bunch of things that we'll need specifically for an HTTP interceptor that we need to import. And just for typing purposes, let's import the observable class from our XJS. So now let's define the class for the interceptor. We can decorate it with the injectable decorator and it should implement the HTTP interceptor interface. In order to implement the HTTP interceptor interface correctly, the interceptor must define a method called intercept. The method will return an observable, just like the HTTP methods of the HTTP client. But it will be an observable of an HTTP event rather than an observable of an HTTP response. The event may be for any type of response, and the method will accept two parameters. The first is an object which represents the request. This has a type of HttpRequest, and it may be any type of HttpRequest. The method will also be passed a class called next, which is of the type HttpHandler. The method will also be passed a function called next, which is of the type HttpHandler. So inside the method, then, we can do what we need to do. In this case, we can set the header, although we do have a slight conundrum here. The request objects passed to the interceptor will already have a headers property, and as we already know, the headers are immutable, so we can't just set them. The headers property of the request is read-only as well. So we can't even replace the existing headers with some new ones. And we wouldn't want to do that anyway, as we would have to save any that were already set and make sure they got added to the new headers objects. So instead, the request object has a special method called clone. We can pass an object to this method containing any properties of the request that we want to modify, and Angular will take care of applying the changes to the request. The method returns a modified request object, so we need to make sure that we store this. So we invoke the clone method of the request and we pass it an object. One of the keys within that object is called headers. So we're telling Angular that we want to set some new headers on the cloned version of the request. And in this case, we just want to set the x-requested-with header that we were setting previously. So we've still got some red underlining in the editor here, and that's because the method should be returning an observable. So we can fix that using the next handler that gets passed to the intercept method. The next object has a method called handle and we can pass the modified request object to that method and Angular will take care of passing the modified request onto either the next interceptor in the chain or the HTTP client, if there are no more interceptors. Great, so now we just need to make use of our new interceptor. So this needs to be imported into the same place as the HTTP client is imported, which for us is in our app.module.ts file. And we'll also need to import the collection of HTTP interceptors from Angular. The interceptor needs to be provided but we can't just add it to the providers array in the way that we have been doing previously. We need to use the HTTP interceptors injection token that we just imported. We use an object with the keys provide, useClass, and multi. And what we're saying here, basically, is that anytime Angular injects the collection of HTTP interceptors, it should include our requested-with header interceptor. Multi is set to true to tell Angular the HTTP interceptors token represents a collection of items rather than a single service. So now let's delete where we set the header previously in the game service. And now let's go back to the browser and check that the interceptor is working as expected. And let's take a look at the second item. And we can see that the x-requested-with header is still being set, and we know now that that's coming from the interceptor rather than the site of the original request. So, if we were making 10 or 15 or even 50 other HTTP requests around the application, they would all have this x-requested-with header and we wouldn't need to go through and manually update every single request. So in this lesson we saw how to create an HTTP interceptor. HTTP interceptors form a chain, with each interceptor receiving a request, potentially modifying it, and then passing this request along to the next interceptor in the chain. An HTTP interceptor can be used for many things. In this example, we used it to add a simple request header and we saw that this header will now get applied to every single request made throughout the application. Thanks for watching.