HTTP Client & Observables
HTTP Client Setup
Section titled “HTTP Client Setup”import { provideHttpClient } from '@angular/common/http';
bootstrapApplication(AppComponent, { providers: [provideHttpClient()]});Basic HTTP Requests
Section titled “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 titled “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();
// Or with 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 titled “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
// Or object syntaxthis.http.get(url, { params: { page: '1', limit: '10' }});Interceptors
Section titled “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);};
// Provide in main.tsprovideHttpClient( withInterceptors([authInterceptor]));Error Handling
Section titled “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 titled “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 titled “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 titled “Combining Observables”import { forkJoin, combineLatest } from 'rxjs';
// Wait for all to completeloadData() { 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 });}
// Emit when any changescombineLatest([ this.http.get<User[]>('/users'), this.http.get<Post[]>('/posts')]).subscribe(([users, posts]) => { // Process combined data});Best Practices
Section titled “Best Practices”- Always unsubscribe or use
asyncpipe - Use interceptors for auth, logging, errors
- Type your HTTP responses
- Handle errors gracefully
- Use retry for transient failures
- Cancel requests with
takeUntil()

