Skip to content
Advertisement

Having trouble displaying object property

I’m building a small pokedex using PokeAPI. I’m retrieving data from an endpoint and building my own object. The function that I’ve built for the latter runs on page load as follows:

$: pokemon = []

//fetch pokemon from PokeAPI

function getPokemon(){
let index = 0

fetch("https://pokeapi.co/api/v2/pokemon?limit=151") //
    .then(response => response.json()) //
    .then(allpokemon =>  {
    allpokemon.results.map((poke) => 
    
        pokemon = [...pokemon, {
            index: index++,
            name: poke.name
        }]
    )})
}   


//populate pokemon array on page load
getPokemon()

I’m able to console log the object and traverse it in devtools, and also able to JSON stringify it and display within html. But whenever I try to retrieve a specific attribute, I receive a 500 error. For instance, I’m trying to display the current pokemons name in an h1 tag :

<h1>{pokemon[currentPokemon].name</h1> // this doesn't work

whereas

<h1>{pokemon[currentPokemon]</h1> //this does

This can’t be too complicated of a fix, I just don’t know what I’m missing, because I’ve been traversing objects for what I thought was the correct way for years now. Thank you.

Advertisement

Answer

This line is missing a curly brace at the end

<h1>{pokemon[currentPokemon].name</h1>

Besides that pokemon will initially be an empty array, so independent of currentPokemon the value will be undefined and accessing the key name will give the error Cannot read properties of undefined (reading 'name') which could be solved by adding a questionmark (Optional chaining)

<h1>{pokemon[currentPokemon]?.name}</h1>

There’s no need for the $:, just let pokemon = []
.map() returns an array, so instead of setting pokemon inside the function better assign it the result. The index would be available as second parameter inside .map()

.then(allpokemon =>  {
            pokemon = allpokemon.results.map((poke, index) => {
                return {
                    name: poke.name, // or ...poke, to keep all fields
                    index
                }
            })

Writing the index in the data might not be neccessary if an #each loop is used to display the data

{#each pokemon as p, index}
    <p>
        {index} - {p.name}
    </p>
{/each}
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement