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