HTTP Client
About
Angular has a built-in http request library.
HttpClient dependency is provided using the provideHttpClient helper function in app.config.ts.
Then you may inject the HttpClient service as a dependency of the components, services, or other classes.
Best Practices
It is recommended that you create reusable, injectable services which isolate and encapsulate data access logic.
For example, this UserService encapsulates the logic to request data for a user:
Within the component, you can combine NgIf and the async pipe to render the UI for the data only after it's finished loading.
Configuring features of HttpClient
HttpClientwithFetch
withFetchBy default HttpClient uses XMLHttpRequest api to make requests. Use withFetch feature to switch to fetch api instead.
It has limitations such as not producing upload progress events.
withInterceptors(...)
withInterceptors(...)Configures the set of interceptor functions which will process requests made through HttpClient.
Making Requests
Each HttpClient method for request returns RxJS Observable which, when subscribed, sends the request and then emits the results when the server responds.
The request is ONLY sent if you subscribe to the Observable.
If the data has unknown shape, don't use any, use unknown type as the response type.
HttpClient does not verify if the actual returned data matches the method type asserted.
By default HttpClient assumes that servers will return JSON data.
You may configure different types with
responseType:json: JSON data.text: string data.arraybuffer:ArrayBuffercontaining raw response bytes.blob: A blob instance.
In post requests many different types of values can be provided as request's body, an HttpClient will serialize them accordingly:
string: As plain text.number, boolean, array, object: As JSON data.ArrayBuffer: As raw data from the buffer.Blob: As raw data with theBlob's content type.FormData: Asmultipart/form-dataencoded data.HttpParamsorURLSearchParams: Asapplication/x-www-form-urlencodedformatted string.
Setting URL Parameters
Specify request parameters that should be included in the request URL.
Setting Request Headers
Specify request headers that should be included in the request.
Accessing More Data from the Response
For convenience HttpClient only gets the body from the response.
To access the entire response, set the option observe: 'response'.
Accessing Raw Progress Events
HttpClient can also return a stream of raw events corresponding to specific moments in the request lifecycle.
These events include when:
The request is sent;
The response header is returned;
The body is complete.
These events can also include progress events which report upload and download status for large request or response bodies.
They are disabled by default as they have performance costs.
To observe the event stream, set the option observe: 'events'.
HttpEventType.Sent
The request has been dispatched to the server
HttpEventType.UploadProgress
An HttpUploadProgressEvent reporting progress on uploading the request body
HttpEventType.ResponseHeader
The head of the response has been received, including status and headers
HttpEventType.DownloadProgress
An HttpDownloadProgressEvent reporting progress on downloading the response body
HttpEventType.Response
The entire response has been received, including the response body
HttpEventType.User
A custom event from an Http interceptor
Handling Request Failures
HttpClient will catch errors requests which returns through the Observable error channel.
There are two ways HTTP requests can fail:
A network or connection error - that prevents the request from reaching the server.
Will have a
statuscode of0.An
errorwhich is an instance ofProgressEvent.
The backend receives the request but fails to proccess it, and returns an error response.
Will have a failing
statuscode returned by the server.An
errorwhich is the error from the server.
RxJS offers several operators which can be useful for error handling, like catchError().
It also provides several retry operators for automatically re-subscribing to failed Observables under certain conditions, like retry().
Handling Errors - with Subject
SubjectIf multiple parts of the application would want to get the error from the request.
Handling Errors - with Operator catchError
catchErrorUseful for handling error behind the scenes, like to send statistics.
Http Observable
ObservableEach request method construct an Observable of the requested response type.
HttpClient procudes what RxJS calls cold Observables, meaning that no actual request happens until a subscription takes place.
Each subscription is independent, so multiple subscriptions will trigger multiple requests.
Unsubscribing will abort the in-progress request.
This is very useful if the subscription was done via
asyncpipes, as it will automatically cancel the request if the user navigates away.If you use the Observable with the RxJS combinator
switchMap, this cancellation will clean up any stale requests.
It is strongly recommended that you clean up subscriptions when the component using them is destroyed.
Transforming Request Data - with rxjs/Operators
rxjs/OperatorsInterceptors
HttpClient supports a form of middleware known as interceptor.
There are two types:
functional:The recommended type to use, since they have more predictable behavior.
DI-based:Are interceptors defined as injectable classes and configured through the DI system.
Have the same capabilities as
functionalones.
Interceptors are generally function which you can run for each request.
You can make a chain of interceptors where each interceptor processes the request or response before forwarding it to the next interceptor in the chain.
Some commom uses
Adding authentication headers to outgoing requests to a particular API.
Retrying failed requests with exponential backoff.
Caching responses for a period of time, or until invalidated by mutations.
Customizing the parsing of responses.
Measuring server response times and log them.
Driving UI elements such as a loading spinner while network operations are in progress.
Collecting and batch requests made within a certain timeframe.
Automatically failing requests after a configurable deadline or timeout.
Regularly polling the server and refreshing results.
Functional Interceptors
The basic form
The basic form is a function which receives the outgoing HttpRequest and a next function representing the next processing step in the interceptor chain.
Configuring Interceptors
You declare the set of interceptors to use through dependency injection, with withInterceptors.
The interceptors are chained in the order that you've listed them in the providers.
Intercepting Responses
Tap into the next returned stream in order to manipulate the response.
Modifying the Request
Most aspects of HttpRequest and HttpResponse instances are immutable, and interceptors cannot directly modify them.
Instead, they apply mutations by clonning these objects with .clone() operation.
The body of a request or response is NOT protected from deep mutations. If an interceptor must mutate the body, take care to handle running multiple times on the same request.
Dependency Injection in Interceptors
Interceptors are run in the injection context of the injector which registered them.
Request and Response Metadata
Often it is useful to include information, in a request, that is not sent to the backend, but specifically meant for interceptors.
HttpRequest have a .context object which stores this kind of metada.
The .context is mutable.
If an interceptor changes the context of a request that is later retried, the same interceptor will observe the context mutation when it runs again.
This is useful for passing state across multiple retries if needed.
Defining the Tokens
Define a new HttpContextToken to act as a key in the .context.
Reading the token inside the Interceptor
Setting context tokens when making the requests
Synthetic Responses
Interceptors are not required to invoke next.
They may instead choose to construct responses through some other mechanims, such as from a cache or by sending the request through an alternate mechanims.
You can construct a response with:
DI-based Interceptors
A DI-based interceptor is an injectable class which implements the HttpInterceptor interface.
These interceptors will run in the order that their providers are registered.
So, in apps with extensive and hierarchical DI configuration, this order can be very hard to predict.
They are configured through a dependency injection multi-provider:
For intercepting the Response:
Last updated
