Angular HTTP Client
Angular provides HttpClient for communicating with backend services over HTTP. It offers a simplified API for HTTP requests with built-in support for interceptors and RxJS.
Setting Up HttpClient
First, import HttpClientModule in your app module:
// app.module.ts
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
HttpClientModule
]
})
export class AppModule { }
Basic HTTP Requests
Inject HttpClient in your service or component:
import { HttpClient } from '@angular/common/http';
constructor(private http: HttpClient) { }
// GET request
getProducts() {
return this.http.get('https://api.example.com/products');
}
// GET with parameters
getProduct(id: number) {
return this.http.get(`https://api.example.com/products/${id}`);
}
// POST request
addProduct(product: Product) {
return this.http.post('https://api.example.com/products', product);
}
// PUT request
updateProduct(product: Product) {
return this.http.put(`https://api.example.com/products/${product.id}`, product);
}
// DELETE request
deleteProduct(id: number) {
return this.http.delete(`https://api.example.com/products/${id}`);
}
Typed Responses
Specify response types for better type safety:
interface Product {
id: number;
name: string;
price: number;
}
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>('https://api.example.com/products');
}
Error Handling
Handle errors using RxJS catchError:
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
getProducts() {
return this.http.get<Product[]>('https://api.example.com/products')
.pipe(
catchError(error => {
console.error('Error:', error);
return throwError('Something went wrong');
})
);
}
HTTP Headers
Add headers to your requests:
import { HttpHeaders } from '@angular/common/http';
const headers = new HttpHeaders()
.set('Content-Type', 'application/json')
.set('Authorization', 'Bearer token123');
getProducts() {
return this.http.get<Product[]>('https://api.example.com/products', { headers });
}
Request Parameters
Add query parameters to GET requests:
import { HttpParams } from '@angular/common/http';
searchProducts(term: string) {
const params = new HttpParams()
.set('q', term)
.set('page', '1');
return this.http.get<Product[]>('https://api.example.com/products', { params });
}
Progress Events
Track upload/download progress:
uploadFile(file: File) {
const formData = new FormData();
formData.append('file', file);
return this.http.post('https://api.example.com/upload', formData, {
reportProgress: true,
observe: 'events'
});
}
Interceptors
Create HTTP interceptors for cross-cutting concerns:
// auth.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler) {
const authReq = req.clone({
headers: req.headers.set('Authorization', 'Bearer token123')
});
return next.handle(authReq);
}
}
// Register in app module
@NgModule({
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
]
})
export class AppModule { }
Retry Failed Requests
Automatically retry failed requests:
import { retry } from 'rxjs/operators';
getProducts() {
return this.http.get<Product[]>('https://api.example.com/products')
.pipe(
retry(3) // Retry up to 3 times before failing
);
}
Debouncing Search Requests
Optimize search requests with debounce:
import { Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
private searchTerms = new Subject<string>();
search(term: string): void {
this.searchTerms.next(term);
}
ngOnInit() {
this.products$ = this.searchTerms.pipe(
debounceTime(300), // wait 300ms after each keystroke
distinctUntilChanged(), // ignore if same as previous term
switchMap(term => term // switch to new observable each time term changes
? this.productService.searchProducts(term)
: of<Product[]>([]))
);
}
Caching Responses
Cache HTTP responses to avoid duplicate requests:
private cache = new Map<string, any>();
getProducts(): Observable<Product[]> {
const url = 'https://api.example.com/products';
if (this.cache.has(url)) {
return of(this.cache.get(url));
}
return this.http.get<Product[]>(url).pipe(
tap(response => this.cache.set(url, response))
);
}
Next: State Management