Reputation: 17894
Going through the WebAPI documentation for URLSearchParams, I didn't find any documentation on passing array as an parameter.
Can anybody help with that?
Upvotes: 88
Views: 110826
Reputation: 76454
You cannot do it by itself, but you can use forEach
or a loop to pass it:
let params = new URLSearchParams();
[2, 3, 5, 7, 11, 13, 17, 19, 'etc'].forEach(item => params.append("primes", item));
console.log(params.toString());
Or, you can even polyfill this:
URLSearchParams.prototype.appendArray = function(array) {
[2, 3, 5, 7, 11, 13, 17, 19, 'etc'].forEach(item => this.append("primes", item))
}
let params = new URLSearchParams();
params.appendArray([2, 3, 5, 7, 11, 13, 17, 19, 'etc']);
console.log(params.toString());
You see, I added an appendArray
function
to the URLSearchParams
prototype, so from now on any object instantiated as a URLSearchParams
object will have an appendArray
function
that expects an array and add append
it. But, if you polyfill, make sure you polyfill before you are to use the method... :)
Upvotes: 1
Reputation: 1
const objectToQuery = (field, obj, prefix = null) => {
let query = "";
if (obj) {
let keys = Object.keys(obj);
keys.forEach((key) => {
if (Array.isArray(obj[key])) {
obj[key].forEach((e) => {
query += "&" + field + (prefix ?? "") + "[" + key + "]" + "[]=" + e;
});
} else if (typeof obj[key] === "object" && !Array.isArray(obj[key])) {
query += objectToQuery(field, obj[key], (prefix ?? "") + "[" + key + "]");
} else {
query += "&" + field + (prefix ?? "") + "[" + key + "]=" + obj[key];
}
});
}
return query;
};
this will convert even complex objects to query e.g
const filter = {
name:'sample',
status:['open','closed'],
attributes:{
color:['red','blue'],
misc:{
other:'someval'
}
}
}
const baseURL = 'http://localhost'
const query = baseURL+'?page=1'+ objectToQuery('filter',filter)
//http://localhost?page=1&filter[name]=sample
//&filter[status][]=open
//&filter[status][]=closed
//&filter[attributes][color][]=red
//&filter[attributes][color][]=blue
//&filter[attributes][misc][other]=someval
Upvotes: 0
Reputation: 9762
The top answers had me thinking you couldn't pass multiple params at once, and that you had to resort to calling .append()
once per param
That's not the case. You can pass an object with keys and values.
const params = new URLSearchParams({name:"Phil Collins",age:72,role:"musician"});
console.log(params.toString());
Output: name=Phil+Collins&age=72&role=musician
Or you can pass an array of keyvaluepair-arrays
const params = new URLSearchParams([["name","Phil Collins"], ["age",72], ["role","musician"]]);
console.log(params.toString());
Upvotes: -1
Reputation: 21
makeSearchParams(link) {
var url = new URL(window.location.protocol + '//' + window.location.host + link);
const params = this.getSearchParams();
for (let key in params) {
if (Array.isArray(params[key])) {
for (let key1 in params[key]) {
url.searchParams.append(key + '[]', params[key][key1]);
}
} else {
url.searchParams.append(key, params[key]);
}
return url;
}
}
Upvotes: 2
Reputation: 380
With a simple reduce you can obtain this natively without installing any third party module
function serializeParams<T extends object>(params: T): string {
return Object.entries(params)
.reduce((acc, [k, v]) => {
if (Array.isArray(v)) {
for (const val of v) {
acc.append(k, val);
}
return acc;
}
acc.append(k, v);
return acc;
}, new URLSearchParams())
.toString();
}
Upvotes: 0
Reputation: 101
An array of key/value pair arrays should work:
let params = new URLSearchParams([['params', 'v1'], ['params', 'v2']]).toString();
console.log(params);
Upvotes: 3
Reputation: 1123
If you want to use @washington-braga's approach but don't want to install lodash:
function buildParams(data) {
const params = new URLSearchParams()
Object.entries(data).forEach(([key, value]) => {
if (Array.isArray(value)) {
value.forEach(value => params.append(key, value.toString()))
} else {
params.append(key, value.toString())
}
});
return params.toString()
}
Upvotes: 21
Reputation: 655
Here is a function that automatically appends array values as multiple entries/keys in the query string.
The difference to other solutions posted already is, that it is simpler to read and only considers arrays - without appending all other object keys again.
function convertToQueryUrl(obj: never): string {
const params = new URLSearchParams(obj);
for (const [key, value] of Object.entries(obj)) {
if (Array.isArray(value)) {
params.delete(key);
value.forEach((v) => params.append(key, v));
}
}
return params.toString();
}
Upvotes: 1
Reputation: 202156
In fact, you can't pass an array directly but you can use several times the append
method:
let params = new URLSearchParams();
params.append('arrayparams', 'val1');
params.append('arrayparams', 'val2');
params.append('arrayparams', 'val3');
console.log(params.toString());
Upvotes: 130
Reputation: 383
In fact this is the simplest functional way:
const url = new URL('http://localhost/')
url.searchParams.append('date[0]', date1)
url.searchParams.append('date[1]', date2)
console.log(url.toString())
For sure you can iterate through an array.
Upvotes: 7
Reputation: 51
const buildParams = (search) => {
if (!search) return "";
const params = new URLSearchParams();
Object.entries(search).forEach(([key, value]) => {
if (Array.isArray(value)) params.append(key, value.join(","));
else params.append(key, value.toString());
});
return `?${params}`;
};
const search = {
types: ['good', 'bad', 'normal'],
id: 777
}
const url = `http://good.com/${buildParams(search)}`;
As a result, you will get http://good.com/?types=good,bad,normal&id=777
Upvotes: 2
Reputation: 526
URLSearchParams can be passed a sequence of pairs, so to have an array of values:
var ids = [1,2,3,4]
var search = new URLSearchParams(ids.map(s=>['id',s]))
var searchString = search.toString()
// "id=1&id=2&id=3&id=4"
// To get the ids from the URL search string
var search_ids = [...search.getAll('id')]
Upvotes: 38
Reputation: 1803
I've used Lodash map
to iterate over objects/arrays and append the params dynamically.
const buildParams = (data) => {
const params = new URLSearchParams();
map(data, (value, key) => {
if (Array.isArray(data[key])) {
map(value, item => params.append(key, item));
} else {
params.append(key, value);
}
});
return params;
};
const params = {
foo: ['a', 'b', 'c'],
bar: 'xyz'
}
const doFetch = fetch(`http://api.com/search?${buildParams(params)}`)
So the final URL will look like: http://api.com/search?foo=a&foo=b&foo=c&bar=xyz
Upvotes: 5