skip to Main Content

I need to map a JavaScript object to query string parameters. I found several related questions on this site, but none that fully met my needs.

The object will consist of strings and arrays, but will not be nested. Here is an example:

var filters = {
    make: ["Ford", "Honda"],
    year: [],
    color: "Black",
    model: ""
}

Here is the code I have:

mapQueryStringParameters = function (params) {
    return params
        ? '?' + Object.entries(params)
            .flatMap(([key, value]) => [value].flat().map(v => [key, v]))
            .map(it => it.join("="))
            .join("&")
        : "";
}

The above code produces the following result, which is almost correct:

"?make=Ford&make=Honda&color=Black&model="

It correctly omits the year empty array, but adds an property for model, which is an empty string. How can I modify so that it omits any property with an empty string?

3

Answers


  1. After flat() inject this filter

    .filter(v => v !== "")
    

    …and continue with the rest of your chain.

    Note that params will be truthy when it is just {}, so if you don’t want to generate the ? character in that case, you’ll need a different logic. Possibly generate the "?" and then remove it if nothing else followed it. Then it will also not generate the "?" when you pass in a non-empty object, but with its properties all set to an empty string:

    mapQueryStringParameters = function (params) {
        return ('?' + Object.entries(params)
                  .flatMap(([key, value]) => 
                    [value].flat()
                           .filter(v => v !== "")
                           .map(v => [key, v]))
                           .map(it => it.join("=")
                   )
                  .join("&")
              ).replace(/^.$/, "") // Remove lonely "?"
    }
    
    var filters = {
        make: ["Ford", "Honda"],
        year: [],
        color: "Black",
        model: ""
    }
    
    const query = mapQueryStringParameters(filters);
    console.log(query);
    Login or Signup to reply.
  2. First I would clean the obejct with:

    Object.keys(obj).forEach(key => {
      if (obj[key] === '' || obj[key].length === 0) {
        delete obj[key];
      }
    });
    

    Then build the URL with:

    const obj = {
      make: 'Nissan',
      color: ['yellow', 'orange', 'blue'],
    };
    
    const result = '?' + new URLSearchParams(obj).toString();
    console.log(result); // 👉️ '?make=Nissan&color=yellow%2Corange%2Cblue'
    
    Login or Signup to reply.
  3. You could filter first and then get the string.

    const
        filters = { make: ["Ford", "Honda"], year: [], color: "Black", model: "" },
        temp = Object
            .entries(filters)
            .filter(([, v]) => v !== '')
            .flatMap(([k, v]) => [].concat(v).map(e => `${k}=${e}`))
            .join(';'),
        result = (temp && '&') + temp;
    
    console.log(result);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search