Walter
Walter

Reputation: 39

Rendering nested object properties from API call in react

I am trying to render text from an API call, text or numbers that are directly accesible from the axios.data object can render normally, nevertheless when inside the axios.data there is another object with its own properties I cannot render because an error shows, the error is 'undefined is not an object (evaluating 'coin.description.en')', over there description is an object; my code is

function SINGLE_COIN(props) {

    const { id } = useParams()
    console.log(id);
    

    const SINGLE_API = `https://api.coingecko.com/api/v3/coins/${id}?tickers=true&market_data=true&community_data=true&developer_data=true&sparkline=true`

    const [coin, setCoin] = useState({})


     useEffect(() => {
        axios
    .get(SINGLE_API)
    .then(res => {
        setCoin(res.data)
        console.log(res.data)
    })
    .catch(error => {
        console.log(error)
    })
    }, [])


    return (


        <div>
           <h2>{coin.name}</h2>
           <div>{coin.coingecko_score}</div>
           <div>{coin.liquidity_score}</div>
           <div>{coin.description.en}</div>


            <SINGLE_COIN_DATA coin={coin} />
        </div>

    )
}

Thanks!

Upvotes: 1

Views: 819

Answers (1)

Prakash S
Prakash S

Reputation: 2073

For the initial render (data is not fetched yet), it will be empty. so nested property would be undefined.

so note the changes:

Example 1:

const [coin, setCoin] = useState(null);

..

return (
    <div>
      {coin ? (
        <>
          <h2>{coin.name}</h2>
          <div>{coin.coingecko_score}</div>
          <div>{coin.liquidity_score}</div>
          <div>{coin.description.en}</div>
        </>
      ) : null}
    </div>
  );

Example:2: Use the optional chaining while accessing nested property

 return (
    <div>
      <h2>{coin?.name}</h2>
      <div>{coin?.coingecko_score}</div>
      <div>{coin?.liquidity_score}</div>
      <div>{coin?.description?.en}</div>
    </div>
  );

And the complete code with : working example

export default function SINGLE_COIN() {
  const { id } = useParams()

  const SINGLE_API = `https://api.coingecko.com/api/v3/coins/${id}?tickers=true&market_data=true&community_data=true&developer_data=true&sparkline=true`;

  const [coin, setCoin] = useState(null);

  useEffect(() => {
    axios
      .get(SINGLE_API)
      .then((res) => {
        setCoin(res.data);
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

  return (
    <div>
      {coin ? (
        <>
          <h2>{coin.name}</h2>
          <div>{coin.coingecko_score}</div>
          <div>{coin.liquidity_score}</div>
          <div>{coin.description.en}</div>
        </>
      ) : null}
    </div>
  );
}

Upvotes: 1

Related Questions