Reputation: 139
I'm trying to make subsequent API calls to get infos about some financial indexes.. After each call, I want to update de indexObject so it has all the data from all the indexes I stored on the indexes array. The problem is, each time setIndexObject is called it overwrites the object, loosing the previous value even when i use the spread operator.
const [indexObject, setIndexObject] = useState({});
const indexes = [
"^GDAXI",
"^BVSP",
"^NDX",
"^DJI",
"^GSPC",
"^IBEX",
"^HSI",
"^BSESN",
"^FTSE",
];
useEffect(() => {
indexes.forEach((index) => {
const options = {
method: "GET",
url:
"https://apidojo-yahoo-finance-v1.p.rapidapi.com/stock/v2/get-summary",
params: { symbol: `${index}`, region: "US" },
headers: {
"x-rapidapi-key":
"----",
"x-rapidapi-host": "apidojo-yahoo-finance-v1.p.rapidapi.com",
},
};
axios
.request(options)
.then(function (response) {
setIndexObject({
...indexObject,
[index]: {
value: response.data.price.regularMarketPrice.fmt,
variation: response.data.price.regularMarketChangePercent.fmt,
},
});
})
.catch(function (error) {
console.error(error);
});
});
}, []);
This is what I am trying to achieve:
{
A:{
value:,
variation:,
},
B:{
value:,
variation,
}
}
Thanks for the help!
Upvotes: 0
Views: 963
Reputation: 648
The problem here is you're looping the request, while the setState
is not synchronous. It is better to populate all the data first, then set the state after that.
const [indexObject, setIndexObject] = useState({});
const handleFetchData = async () => {
const indexes = [
"^GDAXI",
"^BVSP",
"^NDX",
"^DJI",
"^GSPC",
"^IBEX",
"^HSI",
"^BSESN",
"^FTSE",
];
const resultData = {};
for(const index of index) {
const response = await axios.request(); // add your own request here
resultData[index] = response;
}
return resultData;
}
useEffect(() => {
handleFetchData().then(data => setIndexObject(data));
}, []);
why i use for of
? because forEach
or .map
cannot await asynchronous loop.
Or if you want to fetch all the data simultaneously, you can consider using Promise.all
Upvotes: 1