Reputation: 49
I encountered a problem when I try to fetch some data from PokeAPI. Here's my code for PokemonCard component.
import React, { useEffect, useState } from "react";
import axios from "axios";
const PokemonCard = ({ pokemonID }) => {
const [pokemon, setPokemon] = useState({});
useEffect(() => {
(async () => {
const result = await axios.get(
`http://pokeapi.co/api/v2/pokemon/${pokemonID + 1}`
);
setPokemon(result.data);
})();
// console.log(pokemon.weight)
}, [pokemonID]);
return (
<div className="pokemon">
{pokemon.sprites.front_default}
</div>
);
};
export default PokemonCard;
Everything works properly when I try to reach data like: pokemon.weight
or pokemon.base_experience
. But I get errors when I try to use some deeper nested variables.
pokemon.sprites.front_default
gives me an error TypeError:
Cannot read property 'front_default' of undefined.
Here's a sample of data from API:
"name": "bulbasaur",
"order": 1,
"species": {
"name": "bulbasaur",
"url": "https://pokeapi.co/api/v2/pokemon-species/1/"
},
"sprites": {
"back_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/1.png",
"back_female": null,
"back_shiny": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/1.png",
"back_shiny_female": null,
"front_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png",
"front_female": null,
"front_shiny": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/1.png",
"front_shiny_female": null
},
"stats": [
{
"base_stat": 45,
"effort": 0,
"stat": {
"name": "hp",
"url": "https://pokeapi.co/api/v2/stat/1/"
}
}
],
"types": [
{
"slot": 2,
"type": {
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/"
}
},
{
"slot": 1,
"type": {
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/"
}
}
],
"weight": 69
PS. Is it a good practice to make about 150 separate calls to API in every child component? Or should I somehow do it with one call? Thank you.
Upvotes: 0
Views: 1478
Reputation: 17468
Gets much easier in Optional chaining (?.
)
pokemon.sprites?.front_default
Upvotes: 0
Reputation: 870
You were trying to access a key inside an undefined key of pokemon variable. Please check the updated line where you are actually rendering.
{pokemon.sprites ? pokemon.sprites.front_default : ''}
As Pokemon is an empty object before the api fetches the data and updates to the state, so
pokemon.sprites
is actually undefined.
import React, { useEffect, useState } from "react";
import axios from "axios";
const PokemonCard = ({ pokemonID }) => {
const [pokemon, setPokemon] = useState({});
useEffect(() => {
(async () => {
const result = await axios.get(
`http://pokeapi.co/api/v2/pokemon/${pokemonID + 1}`
);
setPokemon(result.data);
})();
// console.log(pokemon.weight)
}, [pokemonID]);
return (
<div className="pokemon">
//this should work for you
{pokemon.sprites ? pokemon.sprites.front_default : ''}
</div>
);
};
export default PokemonCard;
Upvotes: 1