has anyone else found that populating GET
requests in axios is just… awful? I’ve recently fallen back on a simple fetch
because i wasn’t getting nested population data from axios. Just wondering if it’s just me or if this is a known issue.
Do you have example code, please?
Axios and Fetch are just different methods of making HTTP Requests with some differences in what they support with fetch being native.
I think the problem you’re implying is that there are different standards when it comes to stringifying objects and arrays to a query params string.
If you use the params
request config property with your axios requests, chances are that the format that axios produces cannot be read successfully by Strapi, because Strapi uses the qs library for parsing the query params back to an object and expects a different format.
// doesn't out of the box
const restaurantsResponse = await axios.get(`${cmsBaseUrl}/api/restaurants`, {
params: {
populate: ['categories', 'city']
}
});
You have two options to solve this with axios:
- You can either decide to not use the
params
property at all and use qs with every request and add the stringified object to your URL:
const params = qs.stringify({
populate: ['categories', 'city'],
});
const restaurantsResponse = await axios.get(`${cmsBaseUrl}/api/restaurants?${params}`);
- Or you can configure axios’ params serializer on a global level to use qs to stringify the params.
// do this once in your frontend app, eg. in your main.ts or App.ts
axios.interceptors.request.use((axiosRequestConfig) => {
axiosRequestConfig.paramsSerializer = axiosRequestConfig.paramsSerializer
? axiosRequestConfig.paramsSerializer // if you want to still be able to overwrite it on a per-request level
: qs.stringify;
});
// now every request's params gets stringified with qs so that Strapi can parse it correctly
const restaurantsResponse = await axios.get(`${cmsBaseUrl}/api/restaurants`, {
params: {
populate: ['categories', 'city']
}
});
I personally prefer option 2 because I configure it once and then don’t have to worry about it again. The paramsSerializer
can also be configured on a per-request level.
Axios doc:
https://axios-http.com/docs/req_config
qs stringify doc (search for arrayFormat):
agreed as far as what the two do and how they work, what I’m saying is that this url:
/api/orders?populate\[0\]\=items\&populate\[1\]\=items.craft_item
works properly in fetch
(and curl) but not in axios
, as the craft_item
property of each item
isn’t populated
I’m a little distracted by other things at the moment, but I really appreciate this response! I did try most of these things to achieve what I’m doing, but in the end i wound up literally encoding the params in the URL, which I’m not really happy with, but at least works in a fetch
call
but in the end i wound up literally encoding the params in the URL
You really shouldn’t need to do that
/api/orders?populate\[0\]\=items\&populate\[1\]\=items.craft_item
This does look fishy to me will all the escaping and with the dot notation within the param values. The query params should be stringified like this:
const query = qs.stringify({
populate: {
items: ['craft_item'],
},
});
// => 'populate[items][0]=craft_item'
const url = `/api/orders?${query}`
// => `/api/orders?populate[items][0]=craft_item`
same here
it was literally the only permutation that i could get to work, and even then in axios it didn’t populate more than one level