HTTP Client & Observables
HTTP Client Configuration
Section intitulée « HTTP Client Configuration »import { provideHttpClient } from '@angular/common/http';
bootstrapApplication(AppComponent, { providers: [provideHttpClient()]});Basic HTTP Requests
Section intitulée « Basic HTTP Requests »import { HttpClient } from '@angular/common/http';import { inject } from '@angular/core';
@Injectable({ providedIn: 'root' })export class UserService { http = inject(HttpClient); apiUrl = 'https://api.example.com/users';
// GET getUsers() { return this.http.get<User[]>(this.apiUrl); }
// GET by ID getUser(id: number) { return this.http.get<User>(`${this.apiUrl}/${id}`); }
// POST createUser(user: User) { return this.http.post<User>(this.apiUrl, user); }
// PUT updateUser(id: number, user: User) { return this.http.put<User>(`${this.apiUrl}/${id}`, user); }
// PATCH patchUser(id: number, changes: Partial<User>) { return this.http.patch<User>(`${this.apiUrl}/${id}`, changes); }
// DELETE deleteUser(id: number) { return this.http.delete(`${this.apiUrl}/${id}`); }}Using in Component
Section intitulée « Using in Component »@Component({ selector: 'app-user-list', template: ` <div *ngFor="let user of users$ | async"> {{ user.name }} </div> `})export class UserListComponent { userService = inject(UserService); users$ = this.userService.getUsers();
// Ou avec subscribe users: User[] = [];
ngOnInit() { this.userService.getUsers().subscribe({ next: (data) => this.users = data, error: (err) => console.error(err), complete: () => console.log('Complete') }); }}HTTP Headers & Params
Section intitulée « HTTP Headers & Params »import { HttpHeaders, HttpParams } from '@angular/common/http';
// Headersconst headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': 'Bearer token123'});
this.http.get(url, { headers });
// Query paramsconst params = new HttpParams() .set('page', '1') .set('limit', '10') .set('sort', 'name');
this.http.get(url, { params });// GET /api/users?page=1&limit=10&sort=name
// Ou avec la syntaxe objetthis.http.get(url, { params: { page: '1', limit: '10' }});Interceptors
Section intitulée « Interceptors »import { HttpInterceptorFn } from '@angular/common/http';
export const authInterceptor: HttpInterceptorFn = (req, next) => { const token = localStorage.getItem('token');
if (token) { req = req.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); }
return next(req);};
// Fournir dans main.tsprovideHttpClient( withInterceptors([authInterceptor]));Error Handling
Section intitulée « Error Handling »import { catchError, throwError } from 'rxjs';
getUsers() { return this.http.get<User[]>(this.apiUrl).pipe( catchError(error => { console.error('Error:', error); return throwError(() => new Error('Failed to load users')); }) );}
// In componentthis.userService.getUsers().subscribe({ next: data => this.users = data, error: err => this.errorMessage = err.message});Retry & Timeout
Section intitulée « Retry & Timeout »import { retry, timeout } from 'rxjs/operators';
getUsers() { return this.http.get<User[]>(this.apiUrl).pipe( timeout(5000), // 5 seconds retry(3), // Retry 3 times on failure catchError(this.handleError) );}Observable Operators
Section intitulée « Observable Operators »import { map, filter, tap } from 'rxjs/operators';
// Transform datagetActiveUsers() { return this.http.get<User[]>(this.apiUrl).pipe( map(users => users.filter(u => u.active)), tap(users => console.log('Active users:', users)) );}
// Chain requestsgetUserWithPosts(userId: number) { return this.http.get<User>(`/users/${userId}`).pipe( switchMap(user => this.http.get<Post[]>(`/posts?userId=${userId}`).pipe( map(posts => ({ user, posts })) ) ) );}Combining Observables
Section intitulée « Combining Observables »import { forkJoin, combineLatest } from 'rxjs';
// Attendre que toutes les requêtes soient terminéesloadData() { forkJoin({ users: this.http.get<User[]>('/users'), posts: this.http.get<Post[]>('/posts'), comments: this.http.get<Comment[]>('/comments') }).subscribe(({ users, posts, comments }) => { // All data loaded });}
// Émettre lors de changementscombineLatest([ this.http.get<User[]>('/users'), this.http.get<Post[]>('/posts')]).subscribe(([users, posts]) => { // Process combined data});Bonnes Pratiques
Section intitulée « Bonnes Pratiques »- Toujours se désabonner ou utiliser le pipe
async - Utiliser les intercepteurs pour l’auth, le logging, les erreurs
- Typer vos réponses HTTP
- Gérer les erreurs de manière élégante
- Utiliser retry pour les échecs transitoires
- Annuler les requêtes avec
takeUntil()

