Home > Mobile >  React how to make a call to an API and display an array in an array of objects PokeAPI
React how to make a call to an API and display an array in an array of objects PokeAPI

Time:12-15

I need help with a project i am working on, i want to be able to display the moves of a pokemon i type in, i can console.log an array of objects that have smaller arrays inside that i want to grab and display, how can i do so? ive tried the cluster of a method getPokemonNames which is supposed to get the names of the moves of the pokemon but this is where i couldnt think anymore.

import React, {useState} from 'react';
import PokemonName from './PokemonName';
import axios from 'axios';


function App() {
  const [pokemon, setPokemon] = useState([])
  const [loading, setLoading] = useState(false)
  const [moves, setMoves] = useState([])
  
  const getPokemon = async (name) =>{
    setLoading(true);
    const response = await axios.get(`https://pokeapi.co/api/v2/pokemon/${name}`)
    const data = response.data;
    setPokemon(data);
    setMoves(data.moves);
    setLoading(false);
    console.log(data)
    getPokemonNames(data.moves)
    
   // const pokemonMovesAmount = pokemon.moves.map
  }
  const getPokemonNames = (data) =>{
    console.log(data);
    data.move.name.map((moves, key)=>(
      <div key={key}>
        <span>{moves.moves.name}</span>
      </div>
    ))
    
  }
  
  return (
    <>
    <PokemonName getPokemon={getPokemon}/>
    <div>
      {!loading && pokemon ? (<div> 
      </div>): null}
      <img src={pokemon.sprites?.front_default}/>
      <div className="container">
        {getPokemonNames}
      </div>
    </div>
    </>
  );
}

export default App;

this is the pokemon name component

import React, {useState} from 'react'
const onSubmit =(e) =>{
    e.preventDefault();
}
export default function PokemonName(props) {
    const [search, setSearch] = useState('');
   
    return (
        
        <div>
            <div> 
                <h1>{search}</h1>
                <form onSubmit={onSubmit}>
                <input onChange={e => setSearch(e.target.value)} type ="text" placeholder="Search for Pokemon"></input>
                <button onClick={(e) => props.getPokemon(search)}>Search</button>
                </form >
            </div>
        </div>
    )
}

EDIT, this shows a bit more about the data i get back after searching up the pokemon mew enter image description here

CodePudding user response:

First step, making sure you pass the parameter data

const [moves, setMoves] = useState([])
// since you set setMoves to be data.moves second step you can iterate over data only
return (
<>
<PokemonName getPokemon={getPokemon}/>
<div>
  {!loading && pokemon ? (<div> 
  </div>): null}
  <img src={pokemon.sprites?.front_default}/>
  <div className="container">
    {getPokemonNames(moves)}
  </div>
</div>
</>
);

Second step, tweak your getPokemon method

const getPokemonNames = (data) => {
return data.map(moveD, key)=>(
  <div key={key}>
    <span>{moveD.move.name}</span>
  </div>
))
}

CodePudding user response:

There's an error in getPokemonNames() - line 2:

const getPokemonNames = (data) =>{
    data.move.name.map((moves, key)=>(
      <div key={key}>
        <span>{moves.moves.name}</span>
      </div>
    ))
}

It should be

const getPokemonNames = (data) =>{
    data.map(moveData, key)=>(
      <div key={key}>
        <span>{moveData.move.name}</span>
      </div>
    ))
}

The map() function creates a new array from esisting one. So you should have used it to iterate through your repsonse.moves array of moves:

repsonse.moves = [
  {
    move: {
       name: "tackle",
       ...
    }
  },
  {
    move: {
       name: "tackle",
       ...
    }
  },
  {
    move: {
       name: "quickattack",
       ...
    }
  },
  {
    move: {
       name: "flamethrower",
       ...
    }
  }
]

Here's an example applied to my favourite pokemon - Magikarp.

CodePudding user response:

There is an mistake in your getPokemonNames . You are trying to do data.move.name.map which means you are mapping "move" from inside "data". You need to map "moves" array. Here is how you can do it.

const getPokemonNames = (data) =>{
    data.moves.map(item, key)=>(
      <div key={key}>
        <span>{item.move.name}</span>
      </div>
    ))
}
  • Related