HttpClient and Observables
HttpClient is Angular’s built-in service for making HTTP requests. It returns Observables — lazy streams that produce a value when subscribed to. Every API call in CinemaVault goes through HttpClient.
Providing HttpClient
Section titled “Providing HttpClient”In app.config.ts, add provideHttpClient() to the providers array:
import { ApplicationConfig } from '@angular/core';import { provideRouter } from '@angular/router';import { provideHttpClient } from '@angular/common/http';import { routes } from './app.routes';
export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), provideHttpClient() ]};Services that inject HttpClient will now have access to it.
Injecting HttpClient
Section titled “Injecting HttpClient”import { Injectable, inject } from '@angular/core';import { HttpClient } from '@angular/common/http';
@Injectable({ providedIn: 'root' })export class MovieService { private http = inject(HttpClient);}Making a GET request
Section titled “Making a GET request”http.get<T>(url) returns an Observable<T>. The type parameter T tells TypeScript the shape of the response:
interface MoviesResponse { results: Movie[]; total_pages: number; total_results: number;}
getPopular(): Observable<MoviesResponse> { return this.http.get<MoviesResponse>( 'https://api.themoviedb.org/3/movie/popular', { params: { api_key: this.apiKey } } );}The Observable does nothing until something subscribes to it.
Subscribing in components
Section titled “Subscribing in components”Subscribe in ngOnInit to trigger the request:
ngOnInit(): void { this.movieService.getPopular().subscribe({ next: (response) => { this.movies = response.results; this.loading = false; }, error: (err) => { console.error(err); this.loading = false; } });}The subscribe method accepts an observer object with next, error, and optional complete callbacks. next fires when data arrives; error fires on failure.
Transforming responses with map
Section titled “Transforming responses with map”Often you want to extract just the results array from the response. Use map from RxJS:
import { Observable, map } from 'rxjs';
getPopular(): Observable<Movie[]> { return this.http.get<MoviesResponse>( 'https://api.themoviedb.org/3/movie/popular', { params: { api_key: this.apiKey } } ).pipe( map(response => response.results) );}Now components receive Movie[] directly instead of the raw API response object.
Query parameters
Section titled “Query parameters”Pass query parameters via the params option:
discover(genreId: string, year: string, sortBy: string): Observable<Movie[]> { return this.http.get<MoviesResponse>( 'https://api.themoviedb.org/3/discover/movie', { params: { api_key: this.apiKey, with_genres: genreId, primary_release_year: year, sort_by: sortBy } } ).pipe(map(res => res.results));}Angular’s HttpClient automatically URL-encodes the params object.
Observables are lazy
Section titled “Observables are lazy”An Observable from http.get() does not fire a network request until you call .subscribe(). This means:
- You can create an Observable, store it, and subscribe later
- If you never subscribe, no request is made
- Each subscription creates a new request (unlike Promises, which are eager)
In CinemaVault, services return Observables. Components subscribe in ngOnInit. The async pipe in templates subscribes automatically.
Exercise
Section titled “Exercise”- Set up a practice project with
provideHttpClient()inapp.config.ts. - Create a
JsonServicethat injectsHttpClientand has agetTodos(): Observable<any[]>method that fetcheshttps://jsonplaceholder.typicode.com/todos?_limit=5. - Inject
JsonServiceinto a component and subscribe inngOnInit. - Display the results in the template with
@for. - Add a
loading = trueflag and set it tofalsein thenextcallback.
- Register
HttpClientwithprovideHttpClient()inapp.config.ts. - Inject
HttpClientin services withprivate http = inject(HttpClient). http.get<T>(url, options)returns anObservable<T>— lazy, typed.- Subscribe in
ngOnInitwith{ next: fn, error: fn }to trigger the request. - Use
.pipe(map(res => res.results))to transform the response before subscribing. - Pass query params as
{ params: { key: value } }— Angular URL-encodes them automatically.