thelos999
thelos999

Reputation: 653

React, Axios, PokeAPI return undefined when setting hook using "nested" fetches

I trying to do a little project making a mini Pokedex to get more familiar with hooks and Axios. I'm trying to pass the Pokemon's URLs given by PokeAPI in order to have an array of Pokemon objects to display all their information. This is the code I have now, but it returns an array of 20 "undefined" elements.

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

axios.get('https://pokeapi.co/api/v2/pokemon/')
  .then(res => {
    setPokemon(res.data.results.map(p => {
      axios.get(p.url)
        .then(res => res.data);
    }));
  });

What could I do, or what am I doing wrong? If I console.log the "res.data" it prints all the objects, but for some reason that information doesn't get set.

Thanks in advance for any help/suggestions.

Upvotes: 2

Views: 958

Answers (2)

hgb123
hgb123

Reputation: 14891

map function returns an array of new values, your function return nothing (the callback function you implemented is wrapped in {} with no return) so it defaults to undefined

You should first get the list of pokemons, then grab detail each, and then when all done, map and set value

axios
  .get("https://pokeapi.co/api/v2/pokemon/")
  .then((res) => {
    return res.data.results
  })
  .then((results) => {
    return Promise.all(results.map((res) => axios.get(res.url)))
  })
  .then((results) => {
    setPokemon(results.map((res) => res.data))
  })

Codesandbox demo below

Edit ecstatic-swanson-e6bkt

Upvotes: 2

Michael
Michael

Reputation: 1872

You should use Promise.all to call multiple APIs. Try this:

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

axios.get('https://pokeapi.co/api/v2/pokemon/')
.then(res => {
  const fetches = res.data.results.map(p => axios.get(p.url))
  
  Promise.all(fetches).then(data => {
    setPokemon(data);
  })
});

Upvotes: 0

Related Questions