ezio4df
ezio4df

Reputation: 4105

How to remove empty query params using URLSearchParams?

I was working with query params, and got introduced to URLSearchParams. I am using it to form this kind of object to query,

const x = {
  a: 'hello World'
  b: 23
  c: ''
}
let params = new URLSearchParams(x);
console.log(params.toString()) // a=hello+World&b=23&c=

Here, I dont want to have that c=, as it's ugly, and my API doesn't need that.

So, I want this result a=hello+World&b=23 (without empty query string) But, I couldn't find anything on the MDN Web Docs.

How am I supposed to do that?

Doing the following doesn't work, as it seems to directly mutate the params which affects the forEach:

const x = {
  a: 'hello World',
  b: '',
  c: ''
};

let params = new URLSearchParams(x);
params.forEach((value, key) => { // never reaches `c`
  console.log(key, ' => ', value)
  if (value == '')
    params.delete(key);
});
console.log(params.toString());

Upvotes: 32

Views: 32907

Answers (7)

jnaklaas
jnaklaas

Reputation: 1769

You could reduce the object before passing it to the URLSearchParams constructor, might come in handy if you want to remove other nullish values, such as null or undefined.

let x = {
  a: 500,
  b: '',
  c: undefined,
  d: null
};

// remove undefined and null values
x = Object.fromEntries(Object.entries(x).filter(([_, v]) => v != null)); // prettier-ignore

// OR remove empty strings, undefined and null values
x = Object.fromEntries(Object.entries(x).filter(([_, v]) => (v != null && v != ''))); // prettier-ignore

let params = new URLSearchParams(x).toString()

Upvotes: 2

cfx
cfx

Reputation: 3444

Here's a one-liner that preserves any 0 values:

const x = {
  a: 'hello World',
  b: '',
  c: '',
  d: 0
};

const params = new URLSearchParams(new URLSearchParams(x).toString().replace(/(?:\&|^)[^\&]*?\=(?=\&|$)/g, ''));

console.log(params.toString());

If you want something a bit easier to follow:

const x = {
  a: 'hello World',
  b: '',
  c: '',
  d: 0
};

const params = new URLSearchParams(new URLSearchParams(x).toString().split('&').filter(el => el.split('=').slice(-1) !== '').join('&')).toString();

console.log(params.toString());

Upvotes: 1

Manuvo
Manuvo

Reputation: 889

Here is yet another clean way you can do this:

const x = {
  a: 'hello World',
  b: 23,
  c: ''
};

// Create a new object with only non-empty properties
const y = Object.fromEntries(
  Object.entries(x).filter(([key, value]) => value !== '')
);

// Then use this new object to create URLSearchParams
let params = new URLSearchParams(y);

console.log(params.toString());  // a=hello+World&b=23
  1. Object.entries(x) gives us an array of [key, value] pairs for the x object.
  2. The filter function is used to remove entries where the value is an empty string ('').
  3. Object.fromEntries then takes this filtered array and turns it back into an object.
  4. This resulting object is passed to URLSearchParams, which will only have the entries with non-empty values.

Upvotes: 2

Lucas David
Lucas David

Reputation: 102

In case your are working with the query as a string you can also filter it with a regex :

const query = "a=hello+World&b=23&c=&d=12&e="

query.replace(/\w+=&/g, '').replace(/&\w+=$/, '')
// "a=hello+World&b=23&d=12"

Upvotes: 1

abdelgrib
abdelgrib

Reputation: 1140

Simple way to delete useless params from query in JavaScript ES5+:

for (let param in query) { /* You can get copy by spreading {...query} */
  if (query[param] === undefined /* In case of undefined assignment */
    || query[param] === null 
    || query[param] === ""
  ) {    
    delete query[param];
  }
}
return new URLSearchParams(query).toString();

Upvotes: 6

Rahul Bhobe
Rahul Bhobe

Reputation: 4451

You can iterate over the key-value pair and delete the keys with null values:

const x = {
  a: 'hello World',
  b: '',
  c: ''
};

let params = new URLSearchParams(x);
let keysForDel = [];
params.forEach((value, key) => {
  if (value == '') {
    keysForDel.push(key);
  }
});

keysForDel.forEach(key => {
  params.delete(key);
});

console.log(params.toString());

Upvotes: 23

r712m
r712m

Reputation: 339

A clean way I do it myself is as follows (using lodash):

import omitBy from 'lodash/omitBy';
import isEmpty from 'lodash/isEmpty';

const x = {
  a: 'hello World'
  b: 23
  c: ''
}

const params = new URLSearchParams(omitBy(x, isEmpty));

// mixing other sets
const params = new URLSearchParams({
  otherParam: 'foo', 
  ...omitBy(x, isEmpty)
});

Upvotes: 8

Related Questions