Angular's HttpClient is a robust and versatile service designed for making HTTP requests to remote servers.
As part of the @angular/common/http package, the HttpClient service offers a streamlined API for performing various HTTP operations, including GET, POST, PUT, DELETE, and more.
In this section:
1
delve into using HttpClient to interact with a backend server
In Angular, you can configure your application to include necessary providers and bootstrap it using the bootstrapApplication function.
In this snippet you can see how to set up your application to use HttpClient by defining an application configuration and bootstrapping the main application component.
First, we define an appConfig object of type ApplicationConfig. This configuration object specifies the providers required by the application: in this case, we include provideHttpClient() to enable HTTP services.
After the bootstrap, the HttpClient will be globally available across the whole application
Providers
Providers in Angular are a fundamental concept for the Dependency Injection (DI) system.
They tell the Angular injector how to create instances of dependencies that are needed by various components, services, or other parts of your application.
There are several types of providers in Angular, each used for different scenarios and provideHttpClient is one of them.
We will talk about Dependency Injection in the next chapters
The following script shows how to do a simple GET when the component is mount.
When AppComponent is initialized, it performs an HTTP GET request to the https://jsonplaceholder.typicode.com/users endpoint.
Click on the PLAY button below to see how it works:
open the console and you should see the array of 10 users received from the /users endpoint.
app.component.ts
main.ts
src/app.component.ts
src/main.ts
How it works
The inject(HttpClient) function is used to retrieve the HttpClient instance from Angular's dependency injection, aka DI, system (we'll explore DI in one of the next recipes).
The http class property holds an instance of the HttpClient service so you'll be able to use anywhere in your component class.
The subscribe method is used to handle the response from the HTTP request and accepts a function as parameter.
This function will be automatically invoked when the HTTP operation is done and it also receives the "data" received from the server.
Why do we subscribe HttpClient?
Short answer: the HttpClient.get() method returns an Observable
An Observable is a stream of data that can emit multiple values over time.
Observables are lazy, meaning they do not perform any actions or produce values until there is a subscription. This makes them powerful for handling asynchronous operations like HTTP requests, user input, or real-time data streams.
Observable Lifecycle
An observable can emit three types of notifications:
next: Emission of a value. This happens each time the observable produces a value.
error: An error occurs. The observable stops emitting further values and transitions to an error state.
complete: The observable has finished emitting all of its values. No further values will be emitted.
Unsubscribe
If we don't have to listen Observable emissions anymore, we always should unsubscribe it to save memory and CPU (just like we usually do with removeEventListener while listening DOM events)
HttpClient only emits one value
When using HttpClient, subscribing the get() method activates the observable, causing the HTTP request to be executed.
Anyway, the get() method is a special observable that only emits one value (or an error) and, after that, it completes:
What does complete mean?
It means that the observable has finished to emit values.
So we don't need to manually unsubscribe this observable after its usage since its stream is internally completed and closed (it invokes a cleanup function behind the scenes).
Honestly this is a simplified explanation. Unsubscribe an observable is always a good choice. Read this article to get more details: Why you HAVE to unsubscribe from Observable
Why don't use native fetch instead?
This is a common question.
Why Angular uses Observables to make an Http Request instead of using the native fetch API?
The main reason is that Angular is completely based on Observables: forms, router, components and several other Angular features / API use Observable behind the scenes. And HttpClient returns an observable too so it's perfectly integrated with Angular’s reactive programming model.
So, when / if you'll learn RxJS in depth you'll understand how to compose multiple observables in a unique stream.
Compose observables allow to handle complex scenarios, handle errors and make amazing stuff in a powerful and reactive way.
This topic is complex, so don't worry if something is still not clear.
Anyway it's not really important now while you're understanding how HttpClient works.
Quiz
What is the function to use in the 'providers' configuration of an Angular Standalone project to provide the HttpClient instance:
using .get<any[]> we are telling TypeScript that the HTTP GET request will return an array, although we are not currently enforcing any specific type for the elements within that array (so it's an array of any items)
Anyway now types match and we can safely store the HTTP response into the signal
Of course you can manually create your custom types.
But there are several free tools to convert JSON files to TypeScript types.
In the following video you can see how you can easily use https://json2ts.vercel.app/ :
Sometimes, something goes wrong: the server may be down, you may not have sufficient permissions to invoke an endpoint, or for any other reason.
How to handle errors?
SWITCH LAYOUT
The first approach, shown below, uses a second function to handle errors.
It worked for years but now this approach is deprecated so you should avoid using it:
src/app.component.ts
This second approach uses the full (observer) object syntax by specifying separate handlers for next (the success, when a value is emitted by an Observable) and the error (if something goes wrong):
src/app.component.ts
Example with errors
Here you can see how we can handle an HTTP error displaying a message in the template:
we create another signal
we define the observer object to handle next emissions (success) and errors
You should use the ngOnInit lifecycle method to make an Http Request when the component is mount.
But we did it in the constructor because I did not want to add too much information to this lesson since we have not yet addressed to the "Components" argument.
You can read more info and learn how to use it in the next lesson where we create a TodoList that use REST API.
There are other ways to handle errors in RxJS, i.e using the catchError RxJS operator.
But this argument is too complicated to be faced now.
In the next recipe we'll see a CRUD example (Create, React, Update, Delete) to develop a simple Todo List that fetch, remove, add and update data from server.