Master Angular HTTP Client for making API requests, handling responses, errors, and implementing interceptors.
Master Angular HTTP Client for making API requests, handling responses, errors, and implementing interceptors.
Learn about Setting Up HttpClient.
1import { bootstrapApplication } from '@angular/platform-browser';
2import { provideHttpClient } from '@angular/common/http';
3import { AppComponent } from './app/app.component';
4
5bootstrapApplication(AppComponent, {
6 providers: [
7 provideHttpClient()
8 ]
9});Learn about Making HTTP Requests.
1import { Injectable, inject } from '@angular/core';
2import { HttpClient } from '@angular/common/http';
3import { Observable } from 'rxjs';
4
5export interface User {
6 id: number;
7 name: string;
8 email: string;
9}
10
11@Injectable({ providedIn: 'root' })
12export class UserService {
13 private http = inject(HttpClient);
14 private apiUrl = 'https://api.example.com';
15
16 // GET request
17 getUsers(): Observable<User[]> {
18 return this.http.get<User[]>(\`\${this.apiUrl}/users\`);
19 }
20
21 // GET with parameters
22 searchUsers(query: string): Observable<User[]> {
23 return this.http.get<User[]>(\`\${this.apiUrl}/users\`, {
24 params: { q: query, limit: '10' }
25 });
26 }
27
28 // POST request
29 createUser(user: User): Observable<User> {
30 return this.http.post<User>(\`\${this.apiUrl}/users\`, user);
31 }
32
33 // PUT request
34 updateUser(id: number, user: User): Observable<User> {
35 return this.http.put<User>(\`\${this.apiUrl}/users/\${id}\`, user);
36 }
37
38 // DELETE request
39 deleteUser(id: number): Observable<void> {
40 return this.http.delete<void>(\`\${this.apiUrl}/users/\${id}\`);
41 }
42}Learn about Error Handling.
1import { HttpClient, HttpErrorResponse } from '@angular/common/http';
2import { Observable, throwError } from 'rxjs';
3import { catchError, retry } from 'rxjs/operators';
4
5@Injectable({ providedIn: 'root' })
6export class ApiService {
7 private http = inject(HttpClient);
8
9 getData(): Observable<any> {
10 return this.http.get('/api/data').pipe(
11 retry(3), // Retry failed request up to 3 times
12 catchError(this.handleError)
13 );
14 }
15
16 private handleError(error: HttpErrorResponse) {
17 if (error.status === 0) {
18 // Client-side or network error
19 console.error('An error occurred:', error.error);
20 } else {
21 // Backend returned an unsuccessful response code
22 console.error(
23 \`Backend returned code \${error.status}, body was: \`,
24 error.error
25 );
26 }
27 return throwError(() => new Error('Something went wrong; please try again later.'));
28 }
29}Learn about HTTP Interceptors.
1import { HttpInterceptorFn } from '@angular/common/http';
2
3// Auth interceptor (functional style - Angular 15+)
4export const authInterceptor: HttpInterceptorFn = (req, next) => {
5 const token = localStorage.getItem('auth_token');
6
7 if (token) {
8 const authReq = req.clone({
9 setHeaders: {
10 Authorization: \`Bearer \${token}\`
11 }
12 });
13 return next(authReq);
14 }
15
16 return next(req);
17};
18
19// Logging interceptor
20export const loggingInterceptor: HttpInterceptorFn = (req, next) => {
21 console.log('HTTP Request:', req.method, req.url);
22 const startTime = Date.now();
23
24 return next(req).pipe(
25 tap({
26 next: () => {
27 const elapsed = Date.now() - startTime;
28 console.log(\`Response received in \${elapsed}ms\`);
29 },
30 error: (error) => {
31 console.error('Request failed:', error);
32 }
33 })
34 );
35};
36
37// Provide interceptors
38bootstrapApplication(AppComponent, {
39 providers: [
40 provideHttpClient(
41 withInterceptors([authInterceptor, loggingInterceptor])
42 )
43 ]
44});Learn about Request Options and Headers.
1import { HttpHeaders, HttpParams } from '@angular/common/http';
2
3@Injectable({ providedIn: 'root' })
4export class DataService {
5 private http = inject(HttpClient);
6
7 // Custom headers
8 getDataWithHeaders(): Observable<any> {
9 const headers = new HttpHeaders()
10 .set('Content-Type', 'application/json')
11 .set('Authorization', 'Bearer token');
12
13 return this.http.get('/api/data', { headers });
14 }
15
16 // Query parameters
17 searchData(filters: any): Observable<any> {
18 let params = new HttpParams();
19 Object.keys(filters).forEach(key => {
20 if (filters[key]) {
21 params = params.set(key, filters[key]);
22 }
23 });
24
25 return this.http.get('/api/search', { params });
26 }
27
28 // Full response (not just body)
29 getFullResponse(): Observable<HttpResponse<any>> {
30 return this.http.get('/api/data', { observe: 'response' });
31 }
32
33 // Track upload progress
34 uploadFile(file: File): Observable<HttpEvent<any>> {
35 const formData = new FormData();
36 formData.append('file', file);
37
38 return this.http.post('/api/upload', formData, {
39 reportProgress: true,
40 observe: 'events'
41 });
42 }
43}Learn about Caching Strategies.
1import { Injectable, inject } from '@angular/core';
2import { HttpClient } from '@angular/common/http';
3import { Observable, of } from 'rxjs';
4import { tap, shareReplay } from 'rxjs/operators';
5
6@Injectable({ providedIn: 'root' })
7export class CachedDataService {
8 private http = inject(HttpClient);
9 private cache = new Map<string, Observable<any>>();
10
11 getData(id: string): Observable<any> {
12 if (!this.cache.has(id)) {
13 this.cache.set(id,
14 this.http.get(\`/api/data/\${id}\`).pipe(
15 shareReplay(1) // Share and replay last emission
16 )
17 );
18 }
19 return this.cache.get(id)!;
20 }
21
22 clearCache(id?: string) {
23 if (id) {
24 this.cache.delete(id);
25 } else {
26 this.cache.clear();
27 }
28 }
29}Always unsubscribe from HTTP observables (or use async pipe)
Use typed responses for better type safety
Implement proper error handling with catchError
Use HTTP interceptors for cross-cutting concerns
Implement retry logic for failed requests
Use shareReplay() to avoid duplicate requests
Keep API URLs in environment configuration
Use loading states to provide user feedback
Test HTTP services with HttpClientTestingModule
HttpClient returns observables that must be subscribed to execute requests
Typed responses provide compile-time type safety and better IDE support
HTTP interceptors enable cross-cutting concerns like authentication and logging
Error handling with catchError prevents stream termination
HttpParams and HttpHeaders provide fluent APIs for request configuration
shareReplay() operator enables response caching and prevents duplicate requests
HTTP observables automatically complete after receiving a response
Progress tracking enables upload/download progress indicators
Functional interceptors (Angular 15+) provide cleaner, more composable request handling
Your progress is saved in this browser, on this device only.