Let's start by taking a look at our sample application here. We have basically two buttons. If I click the first button, we get a list of people here displayed very simply on our HTML part, and we have a raise HTTP error, which basically prints out here the error on the console.
If we look at the implementation, it is quite simple. We import here the HTTP client. Further down, we get an inject in our constructor, and then we basically have these two functions, fetchPeople and raiseHTTPError.
Inside here, we will basically execute simple HTTP requests. Here, for fetching all people, and here, on purpose, we call an unavailable endpoint. Therefore, we raise the HTTP error. What we would like to achieve now is to intercept these HTTP requests.
For that purpose, let's create here our HTTP interceptor file. Now, an HTTP interceptor is nothing more than an Angular service, so let's copy in here the main scaffold of such an Angular service. Then we need to implement a special interface named the HTTP interceptor.
Now, of course, we need to import that as well so we can that from the Angular common HTTP. Let's do that from Angular common HTTP. Great.
Now, the interface usually has a method attached to it. In this case, it is the intercept function, which we need to implement. It comes with a series of parameters. First of all, there's the request itself, which is of type HTTP request. Let's simply put here any. We obviously also need to import that here, always from the same package.
Then we have a next handler, which is an HTTP handler, which we also need to import here. Finally, everything here returns an observable of type HTTP event, of type any, in this case. We also need to import those up here. We need to import the HTTP event, and we also need to import the observable.
Now, to get started, let's simply here create a console log statement processing requests, and let's simply print out a request here. We also need to have that HTTP interceptor pass on the request to the next handler, which could possibly be registered. Therefore, we need to a next.handle and request. We have to return that. Great.
We now need to register it here on our app module. Let's first import our log interceptor here, and we need to register it here in the providers part, as it is a plain, normal Angular service inject. However, we need to register it on the HTTP interceptors, and we need to register it in this way.
We have to say here, provide the HTTP interceptors. Use the class, which is our class in this case. Then specify multi true, because we obviously can register multiple HTTP intercepts, not just one.
Now, let's save this here, and let's have our application refresh. Once the application's refreshed, let's click the fetch button here. We can now see that our log statements get printed out, meaning our HTTP request interceptor gets registered properly.
Now, obviously, we want to do something more interesting. Usually, when we intercept an HTTP, we want to attach some further information, for instance. Let's add some headers. In that case, we create here our custom request, and we need to clone it, actually.
We do request.clone. There's a proper method already here. We can specify the headers array, and say request.headers.set. Let's say app language, set it to Italian.
Now instead, obviously, of passing on our original request, we now pass on our customized cloned request. Once our application refreshes again, let's fetch the people here. Let's open the network request here. Let's clean it out again. Click that people button.
If we make this a bit bigger, we can then scroll down to request headers, and we see here our app language, IT, which gets attached to our request. Great, our interceptor seems to work properly.
Now, in this case, we have just seen how to intercept an HTTP request. Obviously, when the request then comes back from the server, we also want to intercept that response for maybe inspecting it. To do so, we can simply hook onto this handle here, which is actually an observable, and therefore we can apply the normal operators.
Let's have a look. For instance, what we could do here is to register the new function. We will get here an HTTP event of type any. Inside that do function, we can then inspect our event, which we get as a parameter.
If the event is an instance of HTTP response, then we can process the response and inspect it further. For instance, let's simply do a log here, processing response, and print it out. Obviously, we need to return here the event again to get it further processed.
Now, these functions, as you can see here, get highlighted because they haven't been imported. We can here import the HTTP response again from our Angular common HTTP. We obviously need to register here the according RxJS functions.
Again, once our application here refreshes, let's click the fetchPeople. Now, we can see here the processing of the request, and also the processing of the response. Both of these get intercepted correctly.
Now, the last bit that is missing is when we will raise our HTTP error, which we would, of course, also want to intercept, for instance, for doing some logging to our back end server. We can do that by using the catch operator.
As a parameter, we get the response, which again, we can do an instance of, as we did before. If response instance of HTTP error response, in this case, then we can do a simple log, say process same error response, and print it out on our console log here.
We should also then pass this app in the chain. We should do here something like observable.throwResponse. This obviously depends a bit on your use case of your application.
Now, finally, we should import these operators here. First of all, the RxJS operator, catch, but also, the throw of our observable. Great. Let's save it again. Once our application recompiles, let's click that raiseHTTPError.
We can see here that intercepting for our request again, and in this case, the processing of our error response. It gets intercepted as well, just as we want.