3

I have this query string:

"paymentMethod=1&fullname=&persona=&companyName=&countryName=&email=&totalCameras=&camerasOwned=&cameraShares=&snapmailCount=&sessionCount=&createdAtDate=&lastLoginAtDate=&telephone=&sort=created_at%7Cdesc&limit=50&page=1"

and I am trying to delete all empty params and make this into:

"paymentMethod=1&sort=created_at%7Cdesc&limit=50&page=1"

I took this approach:

let searchParams = Object.fromEntries(new URLSearchParams(queryString))
let filteredParams = Object.fromEntries(
  Object.entries(searchParams).filter(([_, value]) => value != "")
)
console.log(new URLSearchParams(filteredParams).toString())
console.log(searchParams)

But I am not sure about this, to use new URLSearchParams twice, is it a better and right approach?

Any guidance would be thankful.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Junaid Farooq
  • 2,484
  • 5
  • 26
  • 63

3 Answers3

7

It's less functional, but you can create a single URLSearchParams object, then iterate over it and .delete keys which have an empty value:

const queryString = "paymentMethod=1&fullname=&persona=&companyName=&countryName=&email=&totalCameras=&camerasOwned=&cameraShares=&snapmailCount=&sessionCount=&createdAtDate=&lastLoginAtDate=&telephone=&sort=created_at%7Cdesc&limit=50&page=1"

const params = new URLSearchParams(queryString);
[...params.entries()].forEach(([key, value]) => {
  if (!value) {
    params.delete(key);
  }
});
const cleaned = String(params);
console.log(cleaned);

The native URLSearchParams.forEach, kind of like getElementsByClassName, is live, so you can't .delete inside it, otherwise the next key-value pair will be skipped - thus the spreading of the .entries iterator first to a new array.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

It's safer to use query-string package.

Define your params as an object than call the stringify method and it will take care of the undefined and empty values for you

params = {
  paymentMethod: 1,
  fullname: 'John',
  created_at: undefined,
  test: '',
};

// cleaned object will be "paymentMethod=1&fullname=John"
const cleaned = queryString.stringify(params);
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Hani Ghazi
  • 100
  • 2
  • 14
  • When I run this code, `cleaned` includes the `test` param even though it's empty `fullname=John&paymentMethod=1&test=` – Duderino9000 Apr 27 '22 at 23:46
  • this is what i did in react. its very useful. dont forget to import and install queryString package let query = { limit: rowsPerPage, offset: pageNo, search: search, status: status, }; Object.keys(query).forEach(key => { if (query[key] === '' || query[key] === null || query[key] === []) { delete query[key]; } }); const queryParams = queryString.stringify(query); – Rana Faraz Feb 14 '23 at 22:10
1
for ([key, value] of searchParams.entries()) {
  if (value == '') searchParams.delete(key)
}
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
szatkus
  • 1,292
  • 6
  • 14
  • 1
    This is not working correctly because iterator skips the next item when we delete an element inside iteration. @CertainPerformance 's solution seems more robust. – sedran Mar 03 '22 at 06:37