Enn Vee
Enn Vee

Reputation: 37

Getting TypeError: _ is undefined when trying to access data that comes from an API

I use this useState hook to store a JSON array inside it.

const [pokemon, setPokemon] = useState([]);

I fetch the data from an API through this useEffect hook

useEffect(async () => {
    const fetchPokemonData = async () => {
        setLoading(true);
        const pokemonDetails = await axios.get(`https://pokeapi.co/api/v2/pokemon-species/${match.params.id}`);
        setPokemon(pokemonDetails.data);
        setLoading(false);
    };
    
    fetchPokemonData();
}, [match])

then I try to display a piece of data through this

<section id="pokemon-info" className="bg-info text-center px-5 col-md-12 col-lg-6 flex-fill">
            <h1>{pokemon.name}({pokemon.names[0].name})</h1></section>

It works sometimes but other times, I get the error

TypeError: pokemon.names is undefined

I'm assuming it has something to do with the data not being loaded in yet. I get the data from this API endpoint https://pokeapi.co/api/v2/pokemon/

Upvotes: 0

Views: 241

Answers (2)

Enn Vee
Enn Vee

Reputation: 37

The problem was pokemon.names was still undefined when React is trying to render the component, thus, giving the error. This happens for any object array that was included by the API when fetching the data. I solved the problem by first checking whether or not the data is accessible. So,

<h1>{pokemon.name}({pokemon.names[0].name})</h1>

becomes

<h1>{pokemon.name}({pokemon.names && pokemon.names[0].name})</h1>

Upvotes: 1

programandoconro
programandoconro

Reputation: 2729

Your Pokemons are inside pokemon.data.results.

Check this example:

import React, { useEffect, useState } from "react";
import "./App.css";
import axios from "axios";

function App() {
  const [pokemon, setPokemon] = useState([]);

  const fetchPokemonData = async () => {
    const pokemonDetails = await axios.get(
      `https://pokeapi.co/api/v2/pokemon/`
    );
    setPokemon(pokemonDetails.data.results[0].name);
    console.log(pokemonDetails.data.results);
  };

  useEffect(() => {
    fetchPokemonData();
  }, []);

  return (
    <div className="App">
      <header className="App-header">
        <section
          id="pokemon-info"
          className="bg-info text-center px-5 col-md-12 col-lg-6 flex-fill"
        >
          <h1>{pokemon}</h1>
        </section>
      </header>
    </div>
  );
}


Upvotes: 0

Related Questions