Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

190
Visualizações
Cannot read properties of undefined error when working with an API in React

I am fetching data from an API which returns an array of objects in this format.

{Name: 'hitmonchan', Description: 'Fighting-type Pokémon introduced in Generation I'}
{Name: 'Gogoat', Description: 'A quadrupedal, hooved Pokémon similar to a goat'}... and so on

Here is what I am attempting to do. I fetch all the pokemons which is over 500, stuff them in an array called allPokemons. Then I want to do stuff with 4 random pokemons from the list. So I will have an array called smallRandomPokemonArray with only four pokemons chosen at random from the allPokemon array.

import { useEffect, useState } from 'react';
import { getallPokemons } from '../services/pokemonapi';

const empty_pokemon = {
    'Name': '',
    'Description': ''
}

function PokemonComponent() {


    const [allPokemons, setAllPokemons] = useState([]);
    const [smallRandomPokemonArray, setSmallRandomPokemonArray] = useState([]);

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

    const getAll = () => {
        getallPokemons()
            .then(data => {

                //actual data with over 500 objects show in log
                console.log(data);
                setAllPokemons(data);
                randomChooser(data.length)
            })
    }

    const randomChooser = (length) => {
        let temporaryArray = [];
        for (let i = 0; i < 4; i++) {
            const randomIndex = Math.floor(Math.random() * length);

            //First Problem: this is returning index in numbers followed by undefined... why?
            console.log(randomIndex + " " + allPokemons[randomIndex]);
            temporaryArray.push(allPokemons[randomIndex]);

            //Second Problem: this is also returning "temp undefined"
            console.log("temp " + temporaryArray[i]);
        }
        setSmallRandomPokemonArray(temporaryArray);
    }

    return (
        <>
            <div className="pokemondiv">
                {
                    smallRandomPokemonArray.map((element) => (
                        <div>
                            <p>{element.Name}</p>
                            <p>{element.Description}</p>
                        </div>
                    ))
                }
            </div>
        </>
    )
}

export default PokemonComponent;

When I try to print values from the setSmallRandomPokemonArray I get that error:

Uncaught TypeError: Cannot read properties of undefined (reading 'Name')

Also, please look at First problem and Second problem part in the code. They are also appearing as undefined in the console.log. From my understanding, it should work because allPokemons already exist when I start to randomize it. Then I just push four random values to the smallRandomPokemonArray. I dont know why its throwing the error.

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Problem

You are calling randomChooser(data.length) just after setAllPokemons(data); in getAll. At this point allPokemons which is used inside randomChooser is still [].

emptyArray[0] = undefined. undefined.Name = Cannot read properties of undefined. The takeaway is that when you call a setState, the related state is updated asynchronously. A re-render is needed to have the updated value.

Solution n° 1

Change getAll to the code below, so its only job is to populate allPokemons state:

const getAll = () => {
  getallPokemons().then((data) => {
    setAllPokemons(data);
  });
};

Use an useEffect to get the the four pokemons you need:

useEffect(() => {  
  /*
    I moved randomChooser here, so you don't have to put it in useEffect's 
    dependencies array, which if you do, you should wrap randomChooser in a 
    useCalback, as otherwise you get an infinite call.
  */
  const randomChooser = (length) => {
    const temporaryArray = [];
    for (let i = 0; i < 4; i++) {
      const randomIndex = Math.floor(Math.random() * length);
      temporaryArray.push(allPokemons[randomIndex]);
    }
    setSmallRandomPokemonArray(temporaryArray);
  };
  if (allPokemons.length <= 0) return;
  randomChooser(allPokemons.length);
}, [allPokemons]);

Solution n° 2

Change randomChooser so that it receives the array, not its length:

const randomChooser = (allPokemons) => {
  let temporaryArray = [];
  for (let i = 0; i < 4; i++) {
    const randomIndex = Math.floor(Math.random() * allPokemons.length);
    temporaryArray.push(allPokemons[randomIndex]);
  }
  setSmallRandomPokemonArray(temporaryArray);
};

Change getAll so you give data to randomChooser:

const getAll = () => {
  getallPokemons().then((data) => {
    setAllPokemons(data);
    randomChooser(data);
  });
};
about 4 years ago · Juan Pablo Isaza Relatório

0

The allPokemons have not been set at the point where you are using it in randomChooser. react will set all state after the function finished running. You need to pass the data into randomChooser.

 const randomChooser = (data) => {
    const length = data.length
    let temporaryArray = [];
    for (let i = 0; i < 4; i++) {
        const randomIndex = Math.floor(Math.random() * length);

        //First Problem: this is returning index in numbers followed by undefined... why?
        console.log(randomIndex + " " + data[randomIndex]);
        temporaryArray.push(data[randomIndex]);

        //Second Problem: this is also returning "temp undefined"
        console.log("temp " + temporaryArray[i]);
    }
    setSmallRandomPokemonArray(temporaryArray);
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda