New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Axios adds array indexes for objects in arrays where it shouldn't #5094
Comments
This is expected behavior. The Let's say we have the following object we want ta pass to the backend: const params = {
users: [
{name: 'abc', age: 27, orders: [1, 2, 3]},
{name: 'qwerty', age: 32, orders: [4, 5, 6]}]
,
data: ['x', 'y']
}; It will be encoded by Axios as So server framework like {
users: [
{ name: 'abc', age: '27', orders: [1, 2, 3] },
{ name: 'qwerty', age: '32', orders: [4, 5, 6] }
],
data: [ 'x', 'y' ]
} But if you encode the params with qs in brackets mode you will get: {"users":[{"name":["abc","qwerty"],"age":["27","32"],"orders":["1","2","3","4","5","6"]}],"data":["x","y"]} Here you can't determine how many orders the user actually has. That is why Axios adds indexes for nested object elements despite the |
Allright, thanks for the detailed information, I understand what you mean. I reported it because my Rails server cannot handle it and it worked before (with I'll check out some more complex query and report back how it works there. Maybe the order of params is important, eg
gets parsed as { "users": [{ "name": "X", orders: ["O1", "O2"] }, { "name": "Y", "orders": ["O3", "O4"] }] } because of the query params order. (just a wild guess though, I have not verified it yet) |
Hmm... If Rails can't handle explicit indexes, then perhaps we should consider adding another encoding mode, since the library size won't increase in this particular case. It was assumed that all frameworks at least can handle encoding using explicit indexes. |
Here are some examples how Rails parses params (tested it in my App): 1. ?a=b
=> {"a":"b"}
2. ?a[]=b
=> {"a":["b"]}
3. ?a[0]=b
=> {"a":{"0":"b"}}
4. ?a[][name]=x
=> {"a":[{"name":"x"}]}
5. ?a[0][name]=x
=> {"a":{"0":{"name":"x"}}
6. ?a[][name]=x&a[][name]=y
=> {"a":[{"name":"x"},{"name":"y"}]}
7. ?a[][name]=x&a[][name]=y&a[][orders]=O1
=> {"a":[{"name":"x"},{"name":"y","orders":"O1"}]}
8. ?a[][name]=x&a[][name]=y&a[][orders][]=O1
=> {"a":[{"name":"x"},{"name":"y","orders":["O1"]}]}
9. ?a[][name]=x&a[][name]=y&a[][orders][]=O1&a[][orders][]=O2
=> {"a":[{"name":"x"},{"name":"y","orders":["O1","O2"]}]}
10. ?a[][name]=x&a[][orders][]=O1&a[][orders][]=O2&a[][name]=y&a[][orders][]=O3&a[][orders][]=O4
=> {"a":[{"name":"x","orders":["O1","O2"]},{"name":"y","orders":["O3","O4"]}]}
11. ?a[][name]=x&a[][orders][]=O1&a[][orders][]=O2&a[][other]=y&a[][orders][]=O3&a[][orders][]=O4
=> {"a":[{"name":"x","orders":["O1","O2","O3","O4"],"other":"y"}]
12. ?a[][name]=x&a[][orders][]=O1&a[][orders][]=O2&a[][other]=y&a[][orders][]=O3&a[][other]=z&a[][orders][]=O4
=> {"a":[{"name":"x","orders":["O1","O2","O3"],"other":"y"},{"other":"z","orders":["O4"]}]} My takeaway is:
But it looks like this method of parsing does not work for every input. I just tested the other way around how Rails encodes these params without a duplicated key: {"a":[{"name":"x"},{"other":"y"}]} It generates an url with this query ... ?a[][name]=x&a[][other]=y ... but if you feed this back to Rails it parses it as ... {"a":[{"name":"x","other":"y"}]} Looks like Rails cannot handle every object in url params 🤷 |
I started a discussion at rack/rack#1974 (this is what Rails uses when parsing params), maybe we get some more info there. |
rack/rack#1974 just confirmed that there is this ambiguity when building queries without indexes. Maybe axios shouldn't care about it then either and generate queries without indexes even if there is a possible ambiguity, because it was always like this? On the other hand something like #5108 would allow to pass an own params serializer (like Though at least people using Rails need this functionality, maybe it is a good idea to support this out of the box with |
Probably, the current |
Yeah, seems good for me. Maybe think about using IMO this is easier to understand from an outside perspective (and you even have the option to add more ways to serialize, who knows). |
Closing cause the custom serializer has been merged |
Hiya! Just popping in here to show my support for a solution like what @DigitalBrainJS suggested. As a RoR developer, a simple way to tell Axios not to put indexes in without having to use a custom serializer would be helpful. This thread was helpful for learning that I needed to do that, though. Keep up the good work, thanks! |
For sending FormData, another option is to pass the data first through https://github.com/therealparmesh/object-to-formdata, since by default that does not add array indexes, even with nested objects. |
I was here a year before today and couldn't find a solution, so I just downgraded my Axios version to 0.2, which was working before upgrading. I realize Ruby on Rails and Laravel have the same issue when receiving a request from Axios. So I'm answering for anyone who will encounter this issue, and for my future self. Here is a solution that seems to work. It rides on paramSerializer which I researched more about after reading it in this issue.
|
Describe the bug
config.paramsSerializer.indexes = false
(default) adds indexes if an object is inside an array but it shouldn't.To Reproduce
https://runkit.com/doits/634530f2d3a446000813ef73
Expected behavior
No
a[0]
buta[]
:// => "/?a[][name]=abc&b[]=x&b[]=y"
Environment
Additional context/Screenshots
None
The text was updated successfully, but these errors were encountered: