Home > Mobile >  TypeError: Cannot read properties of undefined (reading 'total') in React code
TypeError: Cannot read properties of undefined (reading 'total') in React code

Time:07-07

Using the coinranking API to get coin info and the code keeps on throwing this error, I have no idea what's wrong, It was running previously locally but threw that error when I attempted to host it. Now its throwing the error locally as well, I think it has something to do with the syntax in the global stats initialization but I'm not sure how to fix it. Here is the code:

import React from 'react';
import millify from 'millify';
import { Typography, Row, Col, Statistic } from 'antd';
import { Link } from 'react-router-dom';

import { useGetCryptosQuery } from '../services/cryptoApi';
import Cryptocurrencies from './Cryptocurrencies';
import News from './News';
import Loader from './Loader';

const { Title } = Typography;

const Homepage = () => {
  const { data, isFetching } = useGetCryptosQuery(10);
  const globalStats = data?.data?.stats;

  if (isFetching) return <Loader />;

  return (
    <>
      <Title level={2} className="heading">Global Crypto Stats</Title>
      <Row gutter={[32, 32]}>
        <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col>
        <Col span={12}><Statistic title="Total Exchanges" value={millify(globalStats.totalExchanges)} /></Col>
        <Col span={12}><Statistic title="Total Market Cap:" value={`$${millify(globalStats.totalMarketCap)}`} /></Col>
        <Col span={12}><Statistic title="Total 24h Volume" value={`$${millify(globalStats.total24hVolume)}`} /></Col>
        <Col span={12}><Statistic title="Total Cryptocurrencies" value={globalStats.total} /></Col>
        <Col span={12}><Statistic title="Total Markets" value={millify(globalStats.totalMarkets)} /></Col>
      </Row>
      <div className="home-heading-container">
        <Title level={2} className="home-title">Top 10 Cryptos In The World</Title>
        <Title level={3} className="show-more"><Link to="/cryptocurrencies">Show more</Link></Title>
      </div>
      <Cryptocurrencies simplified />
      <div className="home-heading-container">
        <Title level={2} className="home-title">Latest Crypto News</Title>
        <Title level={3}><Link to="/news">Show more</Link></Title>
      </div>
      <News simplified />
    </>
  );
};

export default Homepage;

CodePudding user response:

Try if (isFetching && globalStats) return <Loader />

Initially when rendering, globalStats can happen to be undefined, this way you keep code from breaking when it tries to access property of undefined

CodePudding user response:

This is happening because there is a scenario where isFetching is false AND globalStats is undefined.

When trying to access properties of globalStats while globalStats is undefined, that error will be thrown.

There are 2 ways to solve this

Solution 1:

Add a guard statement to return null or your loading banner (depends what you want your fallback to be):

if (!globalStats) return null; // or return your LoadingBanner

Solution 2:

Everywhere you have globalStats. defined you can optional chain your properties like globalStats?.myProperty and then you can do an empty string as a fallback like this: globalStats?.myProperty || "".

In you scenario you'll need to change your stats content to this:

<Statistic title="Total Cryptocurrencies" value={globalStats?.total || ""} />
<Statistic title="Total Exchanges" value={millify(globalStats?.totalExchanges || "")} />
<Statistic title="Total Market Cap:" value={`$${millify(globalStats?.totalMarketCap || "")}`} />
<Statistic title="Total 24h Volume" value={`$${millify(globalStats?.total24hVolume || "")}`} />
<Statistic title="Total Cryptocurrencies" value={globalStats?.total || ""} />
<Statistic title="Total Markets" value={millify(globalStats?.totalMarkets "")} />
  • Related