Rishav Sinha
Rishav Sinha

Reputation: 359

Convert an object to a query string

i have the following object

let filters = {
  first_ids: [1,2,3],
  second_ids: [2,4,9]
}

Now, i want to loop over them and then return something like the following.

filters[first_ids][]=1&filters[first_ids][]=2&filters[first_ids][]=3&filters[second_ids][]=2&filters[second_ids][]=4&filters[second_ids][]=9&

What i tried is following, but i know this is not a elegant way.

 let filters = {
  first_ids: [1,2,3],
  second_ids: [2,4,9]
}


let finalFilters = []
let firstFilters = filters.first_ids.map((e) => `filters[first_ids][]=${e}&`)
let secondFilters = filters.second_ids.map((e) => `filters[second_ids][]=${e}&`)
finalFilters.push(firstFilters)
finalFilters.push(secondFilters)
finalFilters.toString().replace(/,/g, "")

Also the filters object can have more keys.

Upvotes: 1

Views: 273

Answers (4)

georg
georg

Reputation: 214969

Here's some generic solution:

function toPhpQueryString(o, key) {
    if (o === null || o === undefined)
        return '';

    if (typeof o !== 'object')
        return key + '=' + encodeURIComponent(o);

    if (Array.isArray(o))
        return o.map(v =>
            toPhpQueryString(v, key + '[]')).join('&');

    return Object.entries(o).map(p =>
        toPhpQueryString(p[1], key + '[' + p[0] + ']')).join('&');
}

//

let filters = {
    first_ids: [1, 2, 3],
    second_ids: [2, 4, 9],
    deep: {
        object: {
            abc: [33, 44],
            xyz: 'hey',
        }
    }
}

qs = toPhpQueryString(filters, 'filters');
console.log(qs)

Upvotes: 1

Andreas Louv
Andreas Louv

Reputation: 47099

Something like this might work:

let filters = {
  first_ids: [1, 2, 3],
  second_ids: [2, 4, 9],
};

const output = Object.entries(filters).flatMap(([name, ids]) => {
  return ids.map(id => {
    return `filters[${encodeURIComponent(name)}]=${encodeURIComponent(id)}`;
  });
}).join('&');

console.log(output)

The main idea is to look though each key, value pair in the object fitlers, then loop though all the ids, and construct the query string fragment, and finally join it on &.

Take a look at Object.entries, Array.prototype.flatMap and encodeURIComponent

Upvotes: 1

Som Shekhar Mukherjee
Som Shekhar Mukherjee

Reputation: 8168

reduce into an array first and then use join.

let filters = {
  first_ids: [1, 2, 3],
  second_ids: [2, 4, 9],
};

const res = Object.entries(filters)
  .reduce((r, [k, v]) => (v.forEach((n) => r.push(`filters[${k}][]=${n}`)), r), [])
  .join("&");

console.log(res)

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386604

You could take a nested approach for generating the string.

const
    filters = { first_ids: [1, 2, 3], second_ids: [2, 4, 9] },
    result = Object
        .entries(filters)
        .flatMap(([k, a]) => a.map(v => `filters[${k}][]=${v}`))
        .join('&');

console.log(result);

Upvotes: 1

Related Questions