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?
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 with Promise.all, and then call .then on that.
One possibility is to tweak your .map attempt so that it has an additional Promise.all:
Promise.all([
fetch(`${baseUrl}/counts?entity=color`),
fetch(`${baseUrl}/counts?entity=brand`),
fetch(`${baseUrl}/counts?entity=category`)
]).then(responses => {
return Promise.all(responses.map(r => r.json()))
})
.then(([x, y, z])=> {
console.log(x, y, z);
});
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 call Promise.all with those final promises.
Promise.all([
fetch(`${baseUrl}/counts?entity=color`).then(val => val.json()),
fetch(`${baseUrl}/counts?entity=brand`).then(val => val.json()),
fetch(`${baseUrl}/counts?entity=category`.then(val => val.json()))
]).then(([x, y, z])=> {
console.log(x, y, z);
});
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.
You could combine your all fetch call and map() to generate an array of promises to easily loop the data:
const baseUrl = "https://jsonplaceholder.typicode.com";
useEffect(() => {
const urls = [`${baseUrl}/todos/1`, `${baseUrl}/todos/2`, `${baseUrl}/todos/3`];
const fetchData = async () => {
try {
const responses = await Promise.all(urls.map(url => fetch(url)));
const data = await Promise.all(responses.map(response => response.json()));
console.log(data);
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With