Lesson 7
Interceptors and Error Handling
Introduction

Welcome to the lesson on Interceptors and Error Handling in Angular! 🎉 In this lesson, we'll explore how interceptors can be used to manage HTTP requests and responses effectively. Interceptors play a crucial role in Angular applications by allowing you to modify requests and handle errors in a centralized manner. By the end of this lesson, you'll be equipped to create an interceptor that adds an authorization header to requests and handles errors gracefully.

Understanding Interceptors in Angular

Interceptors in Angular are a powerful feature that allows you to intercept and modify HTTP requests and responses. They act as middleware, enabling you to perform actions such as adding headers, logging requests, or handling errors before the request reaches the server or the response reaches the client. The primary benefit of using interceptors is the ability to centralize these modifications, leading to cleaner and more maintainable code.

Creating a Basic Interceptor

Let's start by creating a basic interceptor. An interceptor in Angular is defined using the HttpInterceptorFn type. This function takes a request and a next handler as parameters.

TypeScript
1import { HttpInterceptorFn } from '@angular/common/http'; 2 3export const authInterceptor: HttpInterceptorFn = (req, next) => { 4 const authReq = req.clone({ 5 headers: req.headers.set('Authorization', 'Bearer token') 6 }); 7 return next(authReq); 8};

In this example, we define an authInterceptor function that uses the HttpInterceptorFn type. The function takes an HttpRequest and a next handler as parameters. We clone the request and add an Authorization header with a token. The modified request is then passed to the next handler in the chain using next(authReq).

Implementing Error Handling in Interceptors

Interceptors can also be used to handle errors globally. This is particularly useful for providing consistent error management across your application. Let's see how we can implement error handling using RxJS operators.

TypeScript
1import { HttpInterceptorFn } from '@angular/common/http'; 2import { catchError } from 'rxjs/operators'; 3import { throwError } from 'rxjs'; 4 5export const authInterceptor: HttpInterceptorFn = (req, next) => { 6 const authReq = req.clone({ 7 headers: req.headers.set('Authorization', 'Bearer token') 8 }); 9 return next(authReq).pipe( 10 catchError(error => { 11 console.error('HTTP Error:', error); 12 return throwError(error); 13 }) 14 ); 15};

In this code snippet, we use the catchError operator from RxJS to catch any errors that occur during the HTTP request. If an error is caught, we log it to the console and rethrow it using throwError. This allows us to handle errors consistently and provide feedback to users, such as displaying error messages.

Example: AuthInterceptor Implementation

Now, let's walk through the complete implementation of the authInterceptor to see how it all comes together.

TypeScript
1import { HttpInterceptorFn } from '@angular/common/http'; 2import { catchError } from 'rxjs/operators'; 3import { throwError } from 'rxjs'; 4 5export const authInterceptor: HttpInterceptorFn = (req, next) => { 6 const authReq = req.clone({ 7 headers: req.headers.set('Authorization', 'Bearer token') 8 }); 9 return next(authReq).pipe( 10 catchError(error => { 11 console.error('HTTP Error:', error); 12 return throwError(error); 13 }) 14 ); 15};

In this complete example, the authInterceptor function is defined using the HttpInterceptorFn type. The function clones the request to add an Authorization header and uses the catchError operator to handle any errors. This interceptor is then provided in the app module to ensure it is used throughout the application.

Configuring Interceptors in Angular

To use interceptors in your Angular application, you need to configure them in the HttpClient module. This involves declaring the set of interceptors when configuring HttpClient through dependency injection. These are the steps you should take:

  1. Import the Required Modules: Ensure that you import the necessary modules and functions for configuring interceptors.

  2. Declare Interceptors Using withInterceptors: Use the withInterceptors feature to declare the interceptors you want to use. This is done when bootstrapping your application.

Here's an example:

TypeScript
1import { bootstrapApplication } from '@angular/platform-browser'; 2import { provideHttpClient, withInterceptors } from '@angular/common/http'; 3import { AppComponent } from './app.component'; 4import { authInterceptor } from './auth.interceptor'; 5import { loggingInterceptor } from './logging.interceptor'; 6import { cachingInterceptor } from './caching.interceptor'; 7 8bootstrapApplication(AppComponent, { 9 providers: [ 10 provideHttpClient( 11 withInterceptors([authInterceptor, loggingInterceptor, cachingInterceptor]) 12 ) 13 ] 14});

By following these steps, your interceptors will be configured to intercept all HTTP requests made by the HttpClient in your Angular application. This setup allows you to centralize request modifications and error handling, making your codebase cleaner and more maintainable.

Conclusion and Next Steps

In this lesson, we've explored the concept of interceptors in Angular and how they can be used to modify HTTP requests and handle errors. By creating an authInterceptor, you've learned to add authorization headers and implement error handling using RxJS operators. This knowledge will help you manage data interactions and error handling more effectively in your Angular applications.

As you move on to the practice exercises, you'll have the opportunity to apply what you've learned and solidify your understanding. In the next lessons, we'll continue to build on these concepts, further enhancing your skills in Angular development. Keep up the great work! 🚀

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.