如何正确使用数组的公理参数

如何在查询字符串中向数组添加索引?

我试着发送这样的数据:

axios.get('/myController/myAction', { params: { storeIds: [1,2,3] })

然后我得到了这个网址:

http://localhost/api/myController/myAction?storeIds[]=1&storeIds[]=2&storeIds[]=3

所以,我应该得到这个网址:

http://localhost/api/myController/myAction?storeIds[0]=1&storeIds[1]=2&storeIds[2]=3

我应该在 params 选项中添加什么来获得这个 url?

140455 次浏览

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)
}
})

This was better for me:

axios.get('/myController/myAction', {
params: { storeIds: [1,2,3] + ''}

})

In my case, there was already jQuery implemented into my codebase. So I just used the predefined method.

jQuery.param(Object)

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'})
}

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}`)
}
})

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

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('&')}`);

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('&')
}
});

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
}
})

enter image description here

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

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)

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

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 Read more about qs

and declared

const qs = require('qs');

after
const query = qs.stringify({
fields: ['username', 'id'],
populate: {
photo: {
fields: ['url']
},
job: {
fields: ['Job']
}
}
}, {
encodeValuesOnly: true
});

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);
});

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
});
}
},