1

Basically I have an async function that fetches data from the pokeAPI. I go through the data and extract what I need then I want to store that data in a variable for future use. My problem is that once I come out of the function it seems that all the data is undefined however while inside the function the data clearly shows that it is being stored like I want it to be. I've exhausted all possible ideas I can think of for fixing or understanding the problem and am at my wits end here.

const getAllPokemon = async () => {
  try {
    const arr = [];
    const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=5");
    const data = await response.json();
    const pokeResults = data.results;
    for (let pokemon of pokeResults) {
      arr.push(getPokemonData(pokemon));
    }
    return arr;
  } catch (e) {
    return "Unable to find pokemon";
  }
};

const getPokemonData = async (pokemon) => {
  let url = pokemon.url;
  const response = await fetch(url);
  const data = await response.json();
  let pokeObj = new Object();
  pokeObj.name = data.forms[0].name;
  pokeObj.id = data.id;
  return pokeObj;
};


const pokemon = getAllPokemon();
console.log(pokemon);
Cydo Entis
  • 46
  • 3
  • 1
    You are calling `getPokemonData` and `getAllPokemon` without await – adiga Feb 01 '21 at 07:27
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – FZs Feb 01 '21 at 07:39

4 Answers4

0

you trying to run async function in global context in sync way. so, it not returned result yet, so console shows 'undefined'

try to wrap all your code in one global async function (including console.log()) and call it. and don't forget to add 'await' for all your async function calling. it will helps you.

const getAllPokemon = async() => {
  try {
    const arr = [];
    const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=5");
    const data = await response.json();
    const pokeResults = data.results;
    for (let pokemon of pokeResults) {
      arr.push(await getPokemonData(pokemon));
    }
    return arr;
  } catch (e) {
    return "Unable to find pokemon";
  }
};

const getPokemonData = async(pokemon) => {
  let url = pokemon.url;
  const response = await fetch(url);
  const data = await response.json();
  let pokeObj = new Object();
  pokeObj.name = data.forms[0].name;
  pokeObj.id = data.id;
  return pokeObj;
};

(async function() {
  const pokemon = await getAllPokemon();
  console.log(pokemon);
})()
adiga
  • 34,372
  • 9
  • 61
  • 83
Paul Zaslavskij
  • 638
  • 3
  • 9
  • `getAllPokemon` still returns a promise. – adiga Feb 01 '21 at 07:25
  • i forgot about await adding to async call. now updated, thanks for your attention – Paul Zaslavskij Feb 01 '21 at 07:26
  • 1
    Inside the `for` loop as well, `getPokemonData` is being called without await – adiga Feb 01 '21 at 07:27
  • Ok so that makes it so I have the data but is there no way to get it out of the async function so it just sitting in an array for me to use whenever I want? – Cydo Entis Feb 01 '21 at 07:47
  • what you asking about is an architecture question. in context you provide we shows you the way to solve issue with data getting. there are no one universal method to solve your problems whenever it comes. i advice you to read more about programming with async events^ api requests, et.c. – Paul Zaslavskij Feb 01 '21 at 08:29
0

You're returning an array of promises; you can await on Promise.all() to resolve it to an array of values.

Here's a simpler way to write your code, with that change at the end.

async function getAllPokemon() {
  const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=5");
  const data = await response.json();
  return data.results.map(getPokemonData); // an array of promises
}

async function getPokemonData(pokemon) {
  const response = await fetch(pokemon.url);
  const data = await response.json();
  return { name: data.forms[0].name, id: data.id };
}

(async function() {
  const pokemonPromises = await getAllPokemon();
  const pokemon = await Promise.all(pokemonPromises); // Wait for all promises to resolve
  console.log(pokemon);
})()
adiga
  • 34,372
  • 9
  • 61
  • 83
AKX
  • 152,115
  • 15
  • 115
  • 172
0

You are using async function, the function call should be prefixed with await:

const pokemon = await getAllPokemon();
console.log(pokemon);
mnikolic
  • 572
  • 1
  • 5
  • 9
0

const getAllPokemon = async () => {
    try {
        const arr = [];
        const response = await fetch("https://pokeapi.co/api/v2/pokemon?limit=5");
        const data = await response.json();
        const pokeResults = data.results;
        for (let pokemon of pokeResults) {
            arr.push(await getPokemonData(pokemon));
        }
        return arr;
    } catch (e) {
        return arr;
    }
};

const getPokemonData = async (pokemon) => {
    let url = pokemon.url;
    const response = await fetch(url);
    const data = await response.json();
    let pokeObj = new Object();
    pokeObj.name = data.forms[0].name;
    pokeObj.id = data.id;
    return pokeObj;
};
const test = async () => {
    const pokemonPromises = getAllPokemon();
    const pokemon = await pokemonPromises;  // Wait for all promises to resolve
    console.log(pokemon);
}

test()

You need to await the promise on the getPokemonData. The function returns a promise and not an object. :

And then you can create another global function, in this case I called it test, Then call it