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
HttpParams class page 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