'Prevent unnecessary '=' in searchParams processing

When processing searchParams, extra = that is added for empty values, results in the wrong URL.
Is there a method to prevent unnecessary = when processing searchParams?

N.B. It would be possible to remove the extra = with RegExp() but that purpose of the question is to achieve it natively with searchParams.

const u = new URL('https://example.com/?4FEE63D94&foo=1');
params = u.searchParams;

params.delete('foo');         // Delete the foo parameter
console.log(u.href);          // https://example.com/?4FEE63D94=

Update

URLSearchParams methods seem to alter URL.
URLSearchParams.entries() & URLSearchParams.forEach() & URLSearchParams.get() replaces + with space (%20).

const u = new URL('https://example.com/?4FEE63D94&foo=1&bar=aaa+bbb+ccc');
let params = u.searchParams;

params.delete('foo');         // Delete the foo parameter
console.log(u.href);          // https://example.com/?4FEE63D94=&bar=aaa+bbb+ccc

u.search = [...params.entries()].map(([key, value]) =>  value ? `${key}=${value}` : key).join('&');
console.log(u.href);          // https://example.com/?4FEE63D94&bar=aaa%20bbb%20ccc

Even params.delete() alters URL. (auth,client to auth%2Cclient)
Note: Run code snippet doesn't show it

const url = 'https://example.com/?4FEE63D94&scope=auth,client&foo=1&bar=aaa+bbb+ccc';
const u = new URL(url);
let params = u.searchParams;
params.delete['foo'];
console.log(u.href);          // https://example.com/?4FEE63D94=&scope=auth%2Cclient&bar=aaa+bbb+ccc

Workaround: Removing unnecessary =

As per suggestion by @Bergi

const u = new URL('https://example.com?4FEE63D94&foo=1&bar=aaa+bbb+ccc');
let params = u.searchParams;

params.delete('foo');         // Delete the foo parameter
console.log(u.href);          // https://example.com/?4FEE63D94=&bar=aaa+bbb+ccc

// URL() params.delete() adds = to all params
u.search = u.search.replace(/=(?=&|$)/g, '');

console.log(u.search);        // ?4FEE63D94&bar=aaa+bbb+ccc
console.log(u.href);          // https://example.com/?4FEE63D94&bar=aaa+bbb+ccc

Performace test

Manual processing vs URLSearchParams

let t;
const n = 100000;

const url = 'https://example.com/?4FEE63D94&scope=auth,client&foo=1&bar=aaa+bbb+ccc';
const u = new URL(url);

t = performance.now();
for (let i = 0; i < n; i++) {
  let params = Object.fromEntries(u.search.substring(1).split('&').map(p => p.split('=')));
  delete params['foo'];
  u.search = Object.entries(params).map(([key, value]) => value ? `${key}=${value}` : key).join('&');
}
console.log(`Operation took ${performance.now() - t} milliseconds`); // 731 millisecond

t = performance.now();
for (let i = 0; i < n; i++) {
  let params = u.searchParams;
  params.delete('foo');
}
console.log(`Operation took ${performance.now() - t} milliseconds`); // 208 millisecond


Solution 1:[1]

The URL class understands search params to be key-value pairs, as mentioned in one of the comments. You need need think about what FEE63D94 is: a key or value?

If it's a key, then it would have an empty value, as in FEE63D94=

If it's a value, then find an appropriate key for it, key=FEE63D94

The other alternative is to have it be part of the path, https://example.com/4FEE63D94?foo=1

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 TheMonarch