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.

parameters set to HttpParams are not working

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 });

parameters set to HttpParams correctly


My gotcha moment was then I found out that HttpParams class in Angular is immutable.

API documentation page for HttpParams
Screenshot from HttpParams class on Angular Docs

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 deprecated URLSearchParams 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.. 🤔

hmm

Related Posts