Reputation: 1453
How to add indexes to array in query string?
I tried send data like this:
axios.get('/myController/myAction', { params: { storeIds: [1,2,3] })
And I got this url:
http://localhost/api/myController/myAction?storeIds[]=1&storeIds[]=2&storeIds[]=3
So, I should to get this url:
http://localhost/api/myController/myAction?storeIds[0]=1&storeIds[1]=2&storeIds[2]=3
What I should add in my params options to get this url?
Upvotes: 135
Views: 220785
Reputation: 494
In React I needed to use axios with a params in array. This was query param:
"fields[0]=username&fields[1]=id&populate[photo][fields][0]=url&populate[job][fields][1]=Job"
to send with axios, for that I installed by CLI
npm install qs
and declared
const qs = require('qs');
after
const query = qs.stringify({
fields: ['username', 'id'],
populate: {
photo: {
fields: ['url']
},
job: {
fields: ['Job']
}
}
}, {
encodeValuesOnly: true
});`<br/>
and finally I called the axios like this:
axios.create({
baseURL: "http://localhost:1337/api/",
}).get(```/users?${query}```) // this parameter show all data
.then((response) => console.log(response.data))
.catch((err) => {
setError(err);
});
Upvotes: 0
Reputation: 1
I am working with nestjs and had to pass array in query, but it didnt successeded, I tried qs and paramsSerialization, but it didn
t work. So I just join array with "," on one server and split it on another with ",". Fortunately, nestjs has @Transform, so it is easy to do.
array: array.join(',')
Code in dto:
@IsArray()
@IsString({ each: true })
@IsOptional()
@Transform(({ value }) => value.split(','))
array: string[];
Upvotes: 0
Reputation: 1404
This behaviour has been added to axios
starting with version 1.0.0
. See paramsSerializer.indexes
at https://github.com/axios/axios/tree/v1.0.0#request-config
Here's an example using your sample code:
axios.get('/myController/myAction', {
params: { storeIds: [1,2,3] },
paramsSerializer: {
indexes: true, // use brackets with indexes
}
)
The resulting query params will have indexes inside the brackets:
/myController/myAction?storeIds[0]=1&storeIds[1]=2&storeIds[2]=3
Other paramsSerializer.indexes
values are null
(no brackets):
axios.get('/myController/myAction', {
params: { storeIds: [1,2,3] },
paramsSerializer: {
indexes: null, // no brackets at all
}
)
// /myController/myAction?storeIds=1&storeIds=2&storeIds=3
And the default false
(brackets without indexes):
axios.get('/myController/myAction', {
params: { storeIds: [1,2,3] },
paramsSerializer: {
indexes: false, // brackets but no indexes
}
)
// /myController/myAction?storeIds[]=1&storeIds[]=2&storeIds[]=3
Upvotes: 31
Reputation: 164
There are a lot of good answers here. But I just wanted to share what I ended up using: (works like a charm even with other non-array parameters in your object)
Here is my params object:
params: {
city: '335471',
size: 4,
page: 1,
type: [1, 2, 3, 4, 5, 6],
}
This is the axios get method:
$axios.get('/some/api/endpoint/', {
params,
paramsSerializer: (params) => parseParams(params),
})
function parseParams(params) {
const keys = Object.keys(params)
let options = ''
keys.forEach((key) => {
const isParamTypeObject = typeof params[key] === 'object'
const isParamTypeArray = isParamTypeObject && params[key].length >= 0
if (!isParamTypeObject) {
options += `${key}=${params[key]}&`
}
if (isParamTypeObject && isParamTypeArray) {
params[key].forEach((element) => {
options += `${key}=${element}&`
})
}
})
return options ? options.slice(0, -1) : options
}
And finally, using this method you will send this request:
https://yourwebsite.com/api/some/api/endpoint/?city=335471&size=4&page=1&type=1&type=2&type=3&type=4&type=5&type=6
source: https://github.com/axios/axios/issues/604#issuecomment-420135579
Upvotes: 2
Reputation: 21
you can create a function as parseParams
that can send the params to this function and serialize it.
axios.get('/myController/myAction', {
params: {
storeIds: [1,2,3]
},
paramsSerializer: params => parseParams(params)
})
parseParams function is;
export const parseParams = (params) => {
let options = '';
for (const [key, value] of Object.entries(params)) {
if (Array.isArray(value)) {
for (const element of value) {
options += `${key}=${element}&`;
}
} else {
options += `${key}=${value}&`;
}
}
return options.slice(0, -1);
};
Upvotes: 1
Reputation: 1127
I had the issue that I wanted axios
to omit brackets altogether. So I ended up with setting the paramsSerializer.indexes
field to null
. You can have the indices set as you want though by setting indexes
to true
.
axiosInstance.defaults.paramsSerializer = {
// e.g. instead of
// storeIds[]=1&storeIds[]=2&storeIds[]=3
// you get
// storeIds[0]=1&storeIds[1]=2&storeIds[2]=3
// with
indexes: true
};
It can also be set per request as it is part of the AxiosRequestConfig
interface:
axios.get(
'/myController/myAction',
{
params: {
storeIds: [1,2,3]
},
paramsSerializer: {
indexes: true
}
}
)
Upvotes: 0
Reputation: 15945
Basically, reading from docs https://axios-http.com/docs/req_config
paramsSerializer
is an optional function, which we should use if the default serialization of params
done by axios
is not as expected.
We can use serialization libraries (which I feel is best approach) to serialize in the params in the paramsSerializer function as per our needs.
Let's see an example.Suppose params is like ...
{
params: {
delay: 1,
ar:[1,2,3]
}
}
then you will get queryString like this ?delay=1&ar[]=1&ar[]=2&ar[]=3
when you make the request, but you might want like this
?delay=1&ar[0]=1&ar[1]=2&ar[2]=3
so in order to get query string as per our format. we can use qs
https://www.npmjs.com/search?q=qs library
and serialize our params in the paramsSerializer
function as below
{
method: "GET",
params: {
delay: 1,
ar:[1,2,3]
},
paramsSerializer: (params) => {
return qs.stringify(params,{
encodeValuesOnly: true
});
}
},
Upvotes: 0
Reputation: 699
This answer is inspired by @Nicu Criste's answer.
But might be not related to the posted question.
The following code was used to generate the query params with repetitive keys which had been supplied with an object array.
Note: If you are a developer with bundlephobia, use the following approach with care: as with UrlSearchParams support varies on different browsers and platforms.
const queryParams = [{key1: "value1"}, {key2: "value2"}]
axios.get('/myController/myAction', {
params: queryParams,
paramsSerializer: params => {
return params.map((keyValuePair) => new URLSearchParams(keyValuePair)).join("&")
}
})
// request -> /myController/myAction?key1=value1&key2=value2
Upvotes: 1
Reputation: 695
I know that this approach is not very good and I don't know the downsides it may have, but i tried this and it worked:
before making the request, prepare the params:
let params = '?';
for (let i = 0; i < YOUR_ARRAY.length; i++) { // In this case YOUR_ARRAY == [1, 2, 3]
params += `storeIds=${YOUR_ARRAY[i]}`; // storeIds is your PARAM_NAME
if (i !== YOUR_ARRAY.length - 1) params += '&';
}
And then make the request like so:
axios.get('/myController/myAction' + params)
Upvotes: 0
Reputation: 337
I got using "paramSerializer" a bit confuse. Before looking for the "right way" to use axios with array querystring on Google, I did following and got working:
var options = {};
var params = {};
for(var x=0;x<Products.length;x++){
params[`VariableName[${x}]`] = Products[x].Id;
}
options.params = params;
axios.get(`https://someUrl/`, options)...
It is going to create querystring parameters like:
VariableName[0]=XPTO,VariableName[1]=XPTO2
which the most webservers expected as array format
Upvotes: 0
Reputation: 170
This work it for me:
axios.get("/financeiro/listar",{
params: {
periodo: this.filtro.periodo + "",
mostrarApagados: this.filtro.mostrarApagados,
mostrarPagos: this.filtro.mostrarPagos,
categoria: this.filtro.categoria,
conta: this.filtro.conta
}
})
Upvotes: -1
Reputation: 927
I rewrote the existing paramSerializer shipped in axios. The following snippet does the same serialization while putting indices between square brackets. I tried qs but it is not compatible with my python connexion backend (for JSON string parameters).
const rcg = axios.create({
baseURL: `${url}/api`,
paramsSerializer: params => {
const parts = [];
const encode = val => {
return encodeURIComponent(val).replace(/%3A/gi, ':')
.replace(/%24/g, '$')
.replace(/%2C/gi, ',')
.replace(/%20/g, '+')
.replace(/%5B/gi, '[')
.replace(/%5D/gi, ']');
}
const convertPart = (key, val) => {
if (val instanceof Date)
val = val.toISOString()
else if (val instanceof Object)
val = JSON.stringify(val)
parts.push(encode(key) + '=' + encode(val));
}
Object.entries(params).forEach(([key, val]) => {
if (val === null || typeof val === 'undefined')
return
if (Array.isArray(val))
val.forEach((v, i) => convertPart(`${key}[${i}]`, v))
else
convertPart(key, val)
})
return parts.join('&')
}
});
Upvotes: 1
Reputation: 387
Without having to add more libraries and using ES6 you could write:
axios.get(`/myController/myAction?${[1,2,3].map((n, index) => `storeIds[${index}]=${n}`).join('&')}`);
Upvotes: 27
Reputation: 31
In my case, I am using someting like this
const params = array.map((v)=>{
return `p=${v}&`
})
Only concat params.join('')
to the URL where you get data:
`url_to_get?${params.join('')`
In my back-end in ASP.net I receive this
[FromUri] string [] p
Upvotes: 1
Reputation: 41
In my case, I use ES6 array function. array element make querystring use reduce function. Object array also works.
const storeIds = [1,2,3]
axios.get('some url', {
params: {
storeIds: storeIds.reduce((f, s) => `${f},${s}`)
}
})
Upvotes: 4
Reputation: 1633
Thanks so much the answer from Nicu Criste, for my case, the API requires params like this:
params: {
f: {
key: 'abc',
categories: ['a','b','c']
},
per_page: 10
}
Method is GET and this API requires the format is: API?f[key]=abc&f[categories][]=a&f[categories][]=b...
So I assigned the paramsSerializer of axios like this:
config.paramsSerializer = p => {
return qs.stringify(p, {arrayFormat: 'brackets'})
}
qs
please go to this link
Upvotes: 17
Reputation: 938
In my case, there was already jQuery implemented into my codebase. So I just used the predefined method.
jQuery.param(Object)
Upvotes: -3
Reputation: 3278
You can use paramsSerializer
and serialize parameters with https://www.npmjs.com/package/qs
axios.get('/myController/myAction', {
params: {
storeIds: [1,2,3]
},
paramsSerializer: params => {
return qs.stringify(params)
}
})
Upvotes: 168