Can't get value from async fetch React

Viewed 32

I make an API fetch which gets back this data:

{
  "id": 1,
  "name": "Apple",
  "symbol": "AAPL",
  "lastPrice": {
    "id": 7,
    "currentPrice": 116.03,
    "openPrice": 115.55,
    "highPrice": 116.75,
    "lowPrice": 115.17,
    "previousClosePrice": 115.17,
    "timeOfRetrieval": "2020-11-26T19:04:35.150+00:00"
  }
}

Here is my React code:

function StockCard(props) {
  const [API, setAPI] = useState("http://localhost:8080/stock/getquote/AAPL")
  const [FetchInterval, setFetchInterval] = useState(300000)
  const [StockData, setStockData] = useState({})

  useEffect(() => {
    FetchData();


    const interval = setInterval(() => {
      FetchData();
    }, FetchInterval)

    return() => clearInterval(interval);

  }, [FetchInterval]);

  const FetchData = async () =>{
    console.log("FETCH CALLED");
    const resp = await Axios.get(API);
          setStockData(resp.data);
          
  }




    return(
        <div>
        <div className='card-container' style={{background: 'linear-gradient(to top, #141e30, #243b55)', padding: '4rem 1rem'}}>
        <CryptoCard
          currencyName={StockData.name}
          currencyPrice={StockData.lastPrice.currentPrice}
          icon={<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/46/Bitcoin.svg/2000px-Bitcoin.svg.png"/>}
          currencyShortName={StockData.symbol}
          trend='(8.54%) $563.47'
          trendDirection={1}
          chartData={[9200, 5720, 8100, 6734, 7054, 7832, 6421, 7383, 8697, 8850]}
        />
        </div>
        </div>
    )
}


export default StockCard;

and it says Cannot read property 'currentPrice' of undefined at this line: currencyPrice={StockData.lastPrice.currentPrice}

If I log out only the StockData, then I get the values but I cannot get that inner object from the original JSON object

What am I doing wrong?

2 Answers

StockData is the empty object initially, so StockData.lastPrice will be undefined. Thus StockData.lastPrice.currentPrice will be the error.

You should check if StockData.lastPrice is undefined before getting the currentPrice field.

<CryptoCard
          currencyName={StockData.name}
          currencyPrice={StockData.lastPrice? StockData.lastPrice.currentPrice : 0}
/>

The first thing is to why its showing can not read property, because whenever react dom render this before setting this value, so you just need to add quick check here, if value is exist then render otherwise use some default value.

use this one.

function StockCard(props) {
  const [API, setAPI] = useState("http://localhost:8080/stock/getquote/AAPL")
  const [FetchInterval, setFetchInterval] = useState(300000)
  const [StockData, setStockData] = useState({})

  useEffect(() => {
    FetchData();


    const interval = setInterval(() => {
      FetchData();
    }, FetchInterval)

    return() => clearInterval(interval);

  }, [FetchInterval]);

  const FetchData = async () =>{
    console.log("FETCH CALLED");
    const resp = await Axios.get(API);
          setStockData(resp.data);
          
  }


   const { lastPrice: {currentPrice}, name, symbol } = StockData || {};

    return(
        <div>
        <div className='card-container' style={{background: 'linear-gradient(to top, #141e30, #243b55)', padding: '4rem 1rem'}}>
        <CryptoCard
          currencyName={name || ''}
          currencyPrice={currentPrice || 0}
          icon={<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/46/Bitcoin.svg/2000px-Bitcoin.svg.png"/>}
          currencyShortName={symbol || ''}
          trend='(8.54%) $563.47'
          trendDirection={1}
          chartData={[9200, 5720, 8100, 6734, 7054, 7832, 6421, 7383, 8697, 8850]}
        />
        </div>
        </div>
    )
}


export default StockCard;
Related