0

passed Json to array and console show empty but with objects inside. but when printing with index console.log show undefind.. whats wrong ?

let pokeName = [];
let pokeId = [];
let pokeImg = [];
let pokeType = [];
let pokeMove = [];

for (let i=1; i< 21; i++) {
    fetch(`https://pokeapi.co/api/v2/pokemon/${i}/`)
        .then(Response => Response.json())
        .then(data => {
            pokeId.push(data['id']);
            pokeName.push(data['name']);

            const dataTypes = data['types'];
            pokeType.push(dataTypes[0]['type']['name']);

            const dataMoves = data['moves'];
            pokeMove.push(dataMoves[0]['move']['name']);

            pokeImg.push(data['sprites']['front_default']);
        });
}


console.log(pokeName);
console.log(pokeId);
console.log(pokeImg);
console.log(pokeMove);
console.log(pokeType);
asportnoy
  • 2,218
  • 2
  • 17
  • 31
  • Your code works, but you are logging the values to the console ***before*** the promise is returned from the `fetch`, meaning the data hasn't been written to the arrays yet. – Sup3rkirby Sep 14 '22 at 19:24

3 Answers3

1

Your console logs are running before your fetch calls are finishing. You can use async/await to solve the issue.

Something like this should work:

let pokeName = [];
let pokeId = [];
let pokeImg = [];
let pokeType = [];
let pokeMove = [];

(async function () {
    for (let i = 1; i < 21; i++) {
        const data = await fetch(`https://pokeapi.co/api/v2/pokemon/${i}/`);
        const json = data.json();

        pokeId.push(json['id']);
        pokeName.push(json['name']);

        const dataTypes = json['types'];
        pokeType.push(dataTypes[0]['type']['name']);

        const dataMoves = json['moves'];
        pokeMove.push(dataMoves[0]['move']['name']);

        pokeImg.push(json['sprites']['front_default']);
    }
})();


console.log(pokeName);
console.log(pokeId);
console.log(pokeImg);
console.log(pokeMove);
console.log(pokeType);
Cyrus
  • 613
  • 1
  • 6
  • 22
1

As I mentioned in my comment, your console.log() code runs before the fetch has returned its promise, and thus no data has been set yet.

for loops actually do not work with the await keyword and so typically you just need to convert your for loop to a for await...of loop instead. Then you can call an async function that loops through all the values you need and once all promises in the loop have been returned, the following code will execute (within the scope of the same function. Any code outside of the function will run asynchronously).

let pokeName = [];
let pokeId = [];
let pokeImg = [];
let pokeType = [];
let pokeMove = [];

let pokeCount = [];
for(let i = 1; i < 21; i++) pokeCount = [...pokeCount, i];

const _FetchPokes = async () => {
  for await (const poke of pokeCount) {
    await fetch(`https://pokeapi.co/api/v2/pokemon/${poke}/`)
      .then(Response => Response.json())
      .then(data => {
        pokeId.push(data['id']);
        pokeName.push(data['name']);
        pokeType.push(data['types'][0]['type']['name']);
        pokeMove.push(data['moves'][0]['move']['name']);
        pokeImg.push(data['sprites']['front_default']);
      });
  }
  
  // This will run AFTER the data has been fetched
  _RunAfterFetch();
}

const _RunAfterFetch = () {
  // Add any code you want to run here
  // This will run AFTER the pokemon data has been fetched
  console.log(pokeName[1-1]);
}

_FetchPokes();
Sup3rkirby
  • 155
  • 1
  • 9
  • thanks! but how do i access seperate arrays ? – danielkalinin Sep 14 '22 at 19:57
  • @danielkalinin What do you mean? Based on what you provided, this stores the data in 5 arrays. The id of each pokemon minus one is the index of each array you'll need. So the pokemon with id **4** (*charmander*) would be `pokeName[(4-1)]` or just `pokeName[3]`. If you wanted all the pokemon data stored together, you would want to use an object, rather than separate arrays. – Sup3rkirby Sep 14 '22 at 20:04
  • i understand but when i do console.log(pokeName[1-1]); after your code i get undefined.. – danielkalinin Sep 14 '22 at 20:09
  • If you are trying to log it after the `_FetchPokes()` line, then this is the same issue with your original code. The pokemon data is fetched *asynchronously*, meaning the rest of the code after that line keeps executing *while* the data is being fetched (as to not freeze up the entire page). That's why my `console.log()` lines are inside of my function. If you want to execute more code, you could call another function (or `console.log()`) inside the `_FetchPokes()` function. – Sup3rkirby Sep 14 '22 at 20:13
  • i meant i wanted to use it outside of _fetchpokes() – danielkalinin Sep 14 '22 at 20:16
  • but is there a way to store data in arrays and use it outside of fetch ? – danielkalinin Sep 14 '22 at 20:17
  • @danielkalinin The data is stored and can be used outside of the `fetch`. The concept here to understand is *when* code runs. Because it takes time to fetch all of the pokemon, you need to have code that waits until all the pokemon data has been fetched, then run. Just adding lines to JavaScript will not do that. Try adding a new function with whatever code you want, and then call that function at the end of `_FetchPokes()`. I'll update my answer to show an example. – Sup3rkirby Sep 14 '22 at 20:22
0

here is the alternate way to fetch data

const getPokemon =async(id)=>{
return await (await fetch(`https://pokeapi.co/api/v2/pokemon/${id}/`)).json();
}

const getSerializedData = async () =>{

for (let i=1; i< 10; i++) {
  const data = await getPokemon(i);
  console.log(data)
  }
}


getSerializedData();
Aman Kumar
  • 121
  • 4