What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Angular’s HttpClient sends an HTTP request only when its returned Observable is subscribed to. That affects when requests run, how often they run, how to cancel them, and how to test them. This guide covers setup, common request shapes, response handling, failures, and tests without a live server.
Configure HttpClient
Import HttpClient from @angular/common/http and inject it where requests are needed. Angular v21 and later make it available for injection by default. Use provideHttpClient(...) in application providers when you need to configure features such as interceptors or XSRF options. For earlier or NgModule-based applications, follow the setup guidance for your Angular version and injector structure.
The default backend uses Fetch. If upload-progress events are required, configure withXhr() to use XMLHttpRequest; Fetch does not support upload progress in Angular. See Angular’s HttpClient setup guide.
Make a request and understand when it runs
HTTP methods such as get, post, put, patch, and delete return RxJS Observables. Creating one does not contact the server: subscribing sends the request. A second subscription to the same Observable sends another request, rather than reusing the first result.
Recommended Free Tools
#1 Best Overall
import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
interface User {
id: number;
name: string;
}
@Injectable({ providedIn: 'root' })
export class UsersService {
private readonly http = inject(HttpClient);
getUser(id: number) {
return this.http.get<User>(`/api/users/${id}`);
}
}
Calling getUser(42) constructs an Observable. It sends the request only when something subscribes—for example, a component’s async pipe or a direct subscription. Angular recommends keeping data-access logic in reusable injectable services rather than scattering request construction through components. The Making HTTP requests guide explains the available methods and options.
Choose how the subscription is managed
- Use the
asyncpipe in a template ortoSignalwhen their integration fits the component; they manage subscription disposal. - For a manual subscription, arrange to unsubscribe when its owner is finished. Unsubscribing aborts an in-progress request.
- Account for multiple subscriptions: if two consumers subscribe independently to the same cold request Observable, each subscription makes a request.
Choose the response shape
By default, HttpClient expects JSON and emits the response body. Select another response mode when the endpoint returns a different format or when code needs headers and status.
Rank #2
| Need | Option | What the Observable emits |
|---|---|---|
| JSON body | Default, or get<T>(url) |
Parsed response body |
| Plain text | responseType: 'text' |
Text body |
| Binary data in an ArrayBuffer | responseType: 'arraybuffer' |
ArrayBuffer body |
| Binary data as a Blob | responseType: 'blob' |
Blob body |
| Status and headers as well as body | observe: 'response' |
Full HTTP response |
| Request lifecycle and progress events | observe: 'events' with relevant reporting enabled |
HTTP event stream |
Progress reporting is off by default because it has a performance cost. Use the full-response or event form only when the additional information is useful. These options affect TypeScript’s inferred return type; when extracting options into a variable, preserve literal values, for example responseType: 'text' as const.
Treat generic response types as assertions
get<User>(...) tells TypeScript that the application expects a User. It does not inspect the response at runtime or prove that the server sent those fields. If the response shape is uncertain or untrusted, use unknown and validate or narrow it before relying on its properties. Avoid treating the generic as runtime validation.
Rank #3
Handle errors and timeouts
Request failures arrive through the Observable error channel as HttpErrorResponse. Angular’s documentation distinguishes three causes:
- Network or connection failure: status is
0. - Configured timeout: status is
0. - Backend error response: the response carries the server’s status and error details.
Use catchError to translate a failure into a state the UI can display, or to report it. Retry only when repeating the operation is appropriate; retry operators resubscribe, so they can repeat a request and its effects.
Rank #4
import { catchError, of } from 'rxjs';
const user$ = this.http.get<User>('/api/user').pipe(
catchError((error: HttpErrorResponse) => {
// Record or map the failure for the application.
return of(null);
})
);
Import HttpErrorResponse from @angular/common/http in code that uses the type. The request option timeout is measured in milliseconds and applies to the backend HTTP request itself; it does not include delay added by interceptors. A timeout therefore is not necessarily a deadline for the entire Observable pipeline.
Be cautious with user-controlled URLs during SSR
Angular notes that, in Node.js server-side rendering, Undici does not enforce browser CORS checks. If a request destination can be influenced by a user, validate it against an allowlist rather than relying on browser CORS behavior. Angular’s request guide describes Fetch options and this SSR consideration.
Test requests without contacting a server
Angular’s HTTP testing utilities replace the real backend with a test backend. A test can capture an outgoing request, check its URL or method, provide a mock success or failure response, and verify that no unexpected requests remain.
import { provideHttpClient } from '@angular/common/http';
import {
provideHttpClientTesting,
HttpTestingController
} from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting()
]
});
});
afterEach(() => {
TestBed.inject(HttpTestingController).verify();
});
Configure provideHttpClient(...) before provideHttpClientTesting(). The testing provider replaces parts of the normal client configuration, so reversing the order can discard features such as configured interceptors.
- Configure the client and testing backend in the test providers.
- Exercise the service or component code that subscribes to the request.
- Use
HttpTestingControllerto expect and inspect the request, then flush a mock response or error. - Call
verify()after the test to detect outstanding unexpected requests.
For example, a test for getUser should subscribe or otherwise consume its Observable before expecting the request; without a subscription, no request has been sent to capture. The official HTTP testing guide documents request matching, flushing responses, and error cases.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




