Search code examples
javascriptreactjsarraysreact-hooksjavascript-objects

React When i am trying to get into a nested object the fetch throws me an undefined error


import React from 'react'
import { useEffect, useState } from 'react'



function PokemonCard() {
const [pokemon, setPokemon] = useState([])
useEffect(() => {
  fetch('https://pokeapi.co/api/v2/pokemon/charizard')
  .then(res => res.json())
  .then(setPokemon)
},[])
const pokemonType = pokemon.types
console.log(pokemonType)

//HERE I GET THE ERROR
pokemonType.map(x => console.log(x.type.name))
return (
<div>
    <h1>{pokemon.name}</h1>
      {/* <img src={pokemon.sprites.front_default}></img> */}
      {/* <h2>Type: {pokemonType}</h2> */}
      <h2>Height: {pokemon.height}</h2>
      <h2>Weight: {pokemon.weight}</h2>
</div>
)
}


export default PokemonCard;

this is the link for the api

https://pokeapi.co/api/v2/pokemon/charizard

when i try to get into the pokemon.types.type.name i get a error saying Uncaught TypeError: Cannot read properties of undefined (reading 'map') at PokemonCard (PokemonCard.js:16:1) at renderWithHooks (react-dom.development.j


Solution

  • That is due to pokemonType is undefined initially. Try using optional chaining operator:

    pokemonType?.map((x) => console.log(x.type.name));
    

    Answer for what you tried in the comment:

    const pokemonType = pokemon.types?.[0]?.type.name;
    

    If you wanted to get the types rendered then use this:

    function PokemonCard() {
      const [pokemon, setPokemon] = React.useState([]);
      React.useEffect(() => {
        fetch("https://pokeapi.co/api/v2/pokemon/charizard")
          .then((res) => res.json())
          .then(setPokemon);
      }, []);
    
      function capitalizeFirstLetter(string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
      }
    
      return (
        <div>
          <h1>{pokemon.name}</h1>
          {pokemon.types &&
            pokemon.types.map(({ type: { name } }) => (
              <p key={name}>{capitalizeFirstLetter(name)}</p>
            ))}
          <h2>Height: {pokemon.height}</h2>
          <h2>Weight: {pokemon.weight}</h2>
        </div>
      );
    }
    
    ReactDOM.render(<PokemonCard />, document.querySelector('.react'));
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <div class='react'></div>