Creating a URL with HttpParams in Angular
Today I learned how to create a URL with query string parameters with HttpParams class in Angular.
I wanted to construct a URL with some query string parameters like: https://api.something.com?id=someid&name=johndoe
I tried:
import { HttpParams } from '@angular/common/http';
...
const baseURL = 'https://api.something.com';
const params = new HttpParams();
params.set('id', 'someid');
params.set('name', 'johndoe');
const fullURL = `${baseURL}?${params.toString()}`;
console.log({ fullURL });
The URL didnโt contain any parameters.
But when I chained .set()
with new HttpParams()
, it works.
const params = new HttpParams()
.set('id', 'someid');
.set('name', 'johndoe');
const fullURL = `${baseURL}?${params.toString()}`;
console.log({ fullURL });
My gotcha moment was then I found out that HttpParams
class in Angular is immutable.
This means params.set()
method doesn't modify an existing params
object - it returns a new HttpParams
instance.
The same goes to append()
and delete()
methods.
append(param: string, value: string): HttpParams;
set(param: string, value: string): HttpParams;
delete(param: string, value?: string): HttpParams;
So if I want the params
object with a new parameter in it, I have to put it in a variable, or reassign to itself.
let params = new HttpParams();
params = params.set('id', 'someid');
params = params.set('name', 'johndoe');
It is opposed to the native URLSearchParams
object, or the deprecatedURLSearchParams
class in @angular/http
module, which are both mutable.
Why Immutable?
I looked up on Google search to find why Angular team decided to make HttpParams class immutable.
I found this post from Sparkles Blog which leads to the official document about immutability of HttpRequest
and HttpResponse
classes.
[โฆ] They are immutable for a good reason: the app may retry a request several times before it succeeds, which means that the interceptor chain may re-process the same request multiple times.
If an interceptor could modify the original request object, the re-tried operation would start from the modified request rather than the original. Immutability ensures that interceptors see the same request for each try.
Source โ Http Guide, Angular.io
Then it is kind of make sense too if the HttpParams
class should be also immutable. It just feels a bit strange though when a.set()
method doesn't actually set something to the caller object.
However, we still cannot always assume that everything is immutable, as mention in another API document page: Instances of HttpRequest class should not be assumed to be immutable.
Hmm.. ๐ค
Originally published at https://armno.in.th on February 24, 2020.