I tried to do 2 data fetches, one to fetch all the products and after that is finished i map all the products and fetch each one of them separately and put them into array. The behaviour that i don't understand occurs when i try to print the results. If i console.log the whole array, everything works fine, but if i try to do it with single array item it returns undefined. Don't ask why i need to fetch all the products separately.
Here's the code.
import React, { useEffect, useState } from "react";
import axios from "axios";
export const Stackoverflow1 = () => {
const [data, setData] = useState("");
const [singleData, setSingleData] = useState("");
const [finished, setFinished] = useState(false);
const API = `${process.env.REACT_APP_SERVER_URL}/api/products`;
useEffect(() => {
const fetchData = () => {
axios.get(API).then((response) => {
setData(response.data);
setFinished(true);
});
};
fetchData();
}, []);
useEffect(() => {
if (finished) {
let list = [];
data &&
data.map(async (item) => {
const API = `${process.env.REACT_APP_SERVER_URL}/api/products/${item.id}`;
axios.get(API).then((response) => {
list.push(response.data);
});
});
setSingleData(list);
}
}, [finished, data]);
return (
<div>
{data &&
singleData &&
data.map((item, index) => (
<div>
{item.name}
{console.log("inside code without index", singleData)}
{console.log("inside code with index", singleData[0])}
</div>
))}
</div>
);
};
//Console logs:
// inside html without index :
// []
// 0: {id: 381, name: 'Akvariumas 30l', description: 'Akvariumas 30l', price: 25.99, image_name: '16491014443.aquael-glossy-100-juodas.jpeg', …}
// 1: {id: 391, name: 'Akvariumas 20l', description: 'akvariumas 20l', price: 12, image_name: '16491031283.aquarium3.jpeg', …}
// 2: {id: 401, name: 'Akvariumas 30l', description: 'Akvariumas 30l', price: 150, image_name: '16491063713.aquarium4.jpeg', …}
// length: 3
// [[Prototype]]: Array(0)
//inside html with index undefined
CodePudding user response:
You should use Promise.all to wait all the promises:
useEffect(() => {
if (finished && data) {
let list = [];
Promise.all(data.map(async (item) => {
const API = `${process.env.REACT_APP_SERVER_URL}/api/products/${item.id}`;
const response = await axios.get(API);
list.push(response.data)
})).then(() => setSingleData(list))
}
}, [finished, data]);