Going through the WebAPI documentation for URLSearchParams, I didn't find any documentation on passing array as an parameter.
Can anybody help with that?
Going through the WebAPI documentation for URLSearchParams, I didn't find any documentation on passing array as an parameter.
Can anybody help with that?
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());
params.getAll('arrayparams') in order to extract the array back out (for those accessing the parameter client side).[].reduce((acc, cur) => { acc.append('arrayparams', cur); return acc; }, new URLSearchParams()).toString()const url = new URL('http://localhost/') url.searchParams.append('date[0]', date1) url.searchParams.append('date[1]', date2) console.log(url.toString())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')]
toString() from search.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()
}
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.
decodeURIComponent on the string: http://localhost/?date[0]=1662178968266&date[1]=1662178968266' I prefer @thierry-templier's response since its more in line with browser's default behavior / spec. To have it be similar to @thierry-templier's answer all you need to do is remove the square brackets from the date string above. The browser allows multiple instance of the same key in the URL - this automatically represents an arrayI'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
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;
}
}
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
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
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();
}
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();
}
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... :)
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());
append for the array property only.