I am fetching an api and pushing results to an empty array, but I need the array to be filled to display the information within the array. I am getting "cannot read property high of undefined" i'm assuming because the array is not filled before rendering, how can I wait for the for loop to be complete before rendering the page?
function TopStocks(props) {
const symbols = ["AAPL", "NFLX", "GOOGL", "TSLA"];
const stockInfo = [];
useEffect(() => {
fetchSymbols();
}, []);
async function fetchSymbols() {
for (let i = 0; i < symbols.length; i++) {
await fetch(
`api&symbol=${symbols[i]}`
)
.then((res) => res.json())
.then((allStocks) => {
try {
let metaDataEntries = allStocks["Meta Data"];
let symbol = metaDataEntries["2. Symbol"].toUpperCase();
let pastDataEntries = allStocks["Time Series (Daily)"];
let pastDataValues = Object.values(pastDataEntries);
let mostRecentValue = pastDataValues[0];
let x = Object.values(mostRecentValue);
let open = parseFloat(x[0]).toFixed(2);
let high = parseFloat(x[1]).toFixed(2);
let low = parseFloat(x[2]).toFixed(2);
let close = parseFloat(x[3]).toFixed(2);
let percentage = close - open;
let result = parseFloat(percentage).toFixed(2);
stockInfo.push({
symbol: symbol,
high: high,
low: low,
close: close,
open: open,
percentage: result,
});
} catch {
console.log("surpassed the limit of 4 requests in under a minute");
}
});
}
}
return (<span className="header__grid-price">{stockInfo[0].high}</span>)
}
You are doing a simple push operation on stockInfo
, which will not trigger the rerender, for that, you have to change the state of it, use useState
hooks instead,
import React, { useEffect, useState } from "react";
function TopStocks(props) {
const symbols = ["AAPL", "NFLX", "GOOGL", "TSLA"];
const [stockInfo, setStockInfo] = useState([]);
useEffect(() => {
fetchSymbols();
}, []);
async function fetchSymbols() {
for (let i = 0; i < symbols.length; i++) {
await fetch(`api&symbol=${symbols[i]}`)
.then((res) => res.json())
.then((allStocks) => {
try {
let metaDataEntries = allStocks["Meta Data"];
let symbol = metaDataEntries["2. Symbol"].toUpperCase();
let pastDataEntries = allStocks["Time Series (Daily)"];
let pastDataValues = Object.values(pastDataEntries);
let mostRecentValue = pastDataValues[0];
let x = Object.values(mostRecentValue);
let open = parseFloat(x[0]).toFixed(2);
let high = parseFloat(x[1]).toFixed(2);
let low = parseFloat(x[2]).toFixed(2);
let close = parseFloat(x[3]).toFixed(2);
let percentage = close - open;
let result = parseFloat(percentage).toFixed(2);
let temp = [...stockInfo];
temp.push({
symbol: symbol,
high: high,
low: low,
close: close,
open: open,
percentage: result
});
setStockInfo(temp);
} catch {
console.log("surpassed the limit of 4 requests in under a minute");
}
});
}
}
return (
<span className="header__grid-price">
{stockInfo[0].high ? stockInfo[0].high : "loading"}
</span>
);
}