Skip to main content
Practice Problems

HttpClient and interceptors in Angular

HttpClient

Angular's HttpClient provides a typed HTTP API built on RxJS Observables. It handles JSON serialization, error handling, and request/response transformation.


Basic Usage

typescript
import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class ApiService { private http = inject(HttpClient); // GET getUsers(): Observable<User[]> { return this.http.get<User[]>('/api/users'); } // GET with params searchUsers(query: string): Observable<User[]> { return this.http.get<User[]>('/api/users', { params: { q: query, limit: '10' } }); } // POST createUser(user: CreateUserDto): Observable<User> { return this.http.post<User>('/api/users', user); } // PUT updateUser(id: string, data: Partial<User>): Observable<User> { return this.http.put<User>(\`/api/users/\${id}\`, data); } // DELETE deleteUser(id: string): Observable<void> { return this.http.delete<void>(\`/api/users/\${id}\`); } }

Error Handling

typescript
import { catchError, retry, throwError } from 'rxjs'; getUsers(): Observable<User[]> { return this.http.get<User[]>('/api/users').pipe( retry(2), // Retry failed requests twice catchError(error => { if (error.status === 404) { return of([]); // Return empty array for 404 } console.error('API Error:', error.message); return throwError(() => new Error('Failed to load users')); }) ); }

HTTP Interceptors

Interceptors modify every HTTP request/response — authentication, logging, error handling, etc.

Functional Interceptor (Modern)

typescript
import { HttpInterceptorFn } from '@angular/common/http'; // Auth interceptor — add token to every request export const authInterceptor: HttpInterceptorFn = (req, next) => { const authService = inject(AuthService); const token = authService.getToken(); if (token) { const cloned = req.clone({ setHeaders: { Authorization: \`Bearer \${token}\` } }); return next(cloned); } return next(req); }; // Logging interceptor export const loggingInterceptor: HttpInterceptorFn = (req, next) => { const started = Date.now(); return next(req).pipe( tap(event => { if (event instanceof HttpResponse) { console.log(\`\${req.method} \${req.url} — \${Date.now() - started}ms\`); } }) ); }; // Error interceptor export const errorInterceptor: HttpInterceptorFn = (req, next) => { return next(req).pipe( catchError((error: HttpErrorResponse) => { if (error.status === 401) { inject(Router).navigate(['/login']); } return throwError(() => error); }) ); };

Register Interceptors

typescript
// main.ts bootstrapApplication(AppComponent, { providers: [ provideHttpClient( withInterceptors([ authInterceptor, loggingInterceptor, errorInterceptor, ]) ), ], });

Common Interceptor Use Cases

Use CaseWhat it does
AuthenticationAdd Bearer token to requests
Error handlingGlobal error toast, redirect on 401
Loading indicatorShow/hide spinner on requests
CachingCache GET responses
RetryRetry failed requests
LoggingLog request/response timing

Important:

HttpClient returns Observables for all HTTP methods — use pipe() with RxJS operators for error handling and transformation. Interceptors are middleware for HTTP requests — use them for auth tokens, error handling, and logging. Prefer functional interceptors (HttpInterceptorFn) over class-based ones.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?
Practice Problems