I have a simple useEffect in my component to fetch data from 3 API calls:
useEffect(() => {
Promise.all([
fetch(`${baseUrl}/counts?entity=color`),
fetch(`${baseUrl}/counts?entity=brand`),
fetch(`${baseUrl}/counts?entity=category`)
]).then(([x, y, z])=> {
console.log(x.json(), y.json(), z.json());
});
}, []);
I’m expecting the actual data I get from the API so that I can use it in my UI, but instead I’m getting this:
I’ve also tried doing this:
useEffect(() => {
Promise.all([
fetch(`${baseUrl}/counts?entity=color`),
fetch(`${baseUrl}/counts?entity=brand`),
fetch(`${baseUrl}/counts?entity=category`)
]).then(responses => responses.map(r => r.json()))
.then(([x, y, z])=> {
console.log(x, y, z);
});
}, []);
I see the desired value inside PromiseResult
, but I’m not sure how to extract it:
What am I doing wrong here. How do I access the array in my code?
4
Answers
The issue is that
.json
returns another promise, so you’d need to call.then
on it to get the eventual value. Or since you’re doing multiple, you’d need to combine it withPromise.all
, and then call.then
on that.One possibility is to tweak your
.map
attempt so that it has an additionalPromise.all
:But that does have the downside that all of the fetches must get far enough along that they resolve, before any of them can call
.json
. This may slightly delay finishing things. So another possibility is to set up all of the work up front, and only callPromise.all
with those final promises.With that version, each of the fetches will go at whatever pace it can manage, and will convert itself to json as soon as it can. Then once all of them are finished, the combined promise resolves.
If you want to use
await
instead ofthen
, this is how I would refactor your code:You could combine your all fetch call and
map()
to generate an array of promises to easily loop the data:Write a
getByEntity
function that wraps a single fetch operation, then mao over the list of entities that you need to retrieve: