Angular 4.3 introduced HTTP interceptors. This gives you the ability to handle every outgoing http call and every incoming response, all in one spot. Most of the examples I've seen out there cover the first, with each call having an authentication token attached to the call. I needed a way to handle and display errors on HTTP calls, and didn't want to put the error handling on every single call I make. This is a quick example of how to implement this in your app.
As I mentioned, HTTP_INTERCEPTORS
was introduced in Angular 4.3. To use them, you need to use the HttpClient
that's in the @angular/common/http
package, not @angular/http
. To write a custom interceptor, you need to implement HttpInterceptor, which requires an intercept method. It's in that method that you can catch errors and handle them. Below is an example:
_ Edit: the first example is for RxJS pre 6.0 release. The second example is for RXJS 6.0+._
// RxJS < 6.0
return next.handle(req)
.do((ev: HttpEvent) => {
if (ev instanceof HttpResponse) {
console.log('ev in the do: ', ev);
}
})
.catch((response: any) => {
if (response instanceof HttpErrorResponse) {
console.log('response in the catch: ', response);
toaster.error('Unexpected Error', response.message);
}
return Observable.throw(response);
});
// RxJS 6.0+
return next.handle(req).pipe(
tap(
(incoming: any) => {},
(error: HttpErrorResponse) => {
// Handle Error
return of(error);
}
)
)
Handling the error here takes place in the catch method. I'll show a little more about where the toaster
variable comes from in a minute, but that's how the errors are globally shown for the app.
For this interceptor to actually work, you need to provide it in the app.module.ts
file, under the providers
attribute for the module. Do that like this:
...
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorInterceptorService,
multi: true
}
...
This is the basic way to catch all the errors globally for your app. I'll now show a little more specifics of the route I took. I am using angular2-toaster
to show the errors when one comes back. I made a service, ToasterNotificationService
, that wraps the package's function to show errors. That service needs to be injected into the interceptor service we made. We need to explicitly use the Angular injector to get an instance of the ToasterNotificationService
. Do that like this:
intercept (req: HttpRequest, next: HttpHandler): Observable> {
const toaster = this.injector.get(ToasterNotificationService);
...
}
Also, make sure to include the custom ToasterNotificationService
, the ToasterModule
(from angular2-toaster), and the ToasterService
into the app.module.ts
's providers and module declarations.
With all of this set up, you should be able to catch the error and then use the toaster notification service to display that error. angular2-toaster has proven to be a simple way to show those errors without having to rewrite a lot of custom code. There is a lot of customization that you can do as well; check out their docs to see that.
Hopefully this all helps you in some way. But to make it a little better, I have put together a little example Angular app to show all this work. It's located right here on GitHub. This StackBlitz project also has an example of this. Check it out, and let me know if you have any questions. You can reach me on Twitter or by email. Thanks for taking the time to read this, and hopefully it helped in some way!
Top comments (0)