24

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());
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
ezio4df
  • 3,541
  • 6
  • 16
  • 31

6 Answers6

20

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());
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Rahul Bhobe
  • 4,165
  • 4
  • 17
  • 32
6

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)
});
r712m
  • 299
  • 3
  • 7
4

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();
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
abdelgrib
  • 843
  • 7
  • 11
1

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"
Lucas David
  • 102
  • 9
1

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.
Manuvo
  • 748
  • 5
  • 15
0

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());
cfx
  • 3,311
  • 2
  • 35
  • 45