0

I've been working on a simple test project, but i happened to come across this really weird problem. I can't access values in an array.

pokemonStats$: Observable<PokemonStats[]>;

getPokemonStats(id: number): any {
this.pokemonStats$
.pipe(take(1))
.subscribe(stats => {
  console.log(stats instanceof Array);
  console.log('length', stats.length);
  console.log('du', stats);
  console.log('test', stats[1]);
});
}

And this is the output:

Output in browser console

What's going on here? A colleague suggested it might be an array-like structure, that's why i added the 'instanceof' log. Any help is greatly appreciated.

EDIT: here's the code, where it gets filled

this.pokemonStats$ = this.getAllPokemonStats(ids);

getAllPokemonStats(ids: number[]): Observable<PokemonStats[]> {
const pokemonArray: PokemonStats[] = [];
ids.forEach(id => {
  const url = 'https://pokeapi.co/api/v2/pokemon/' + id;
  this.http.get(url)
    .pipe(take(1))
    .subscribe((data: PokemonStatsAPI) => {
      pokemonArray.push({
          id: data.id,
          name: data.name,
          speed: data.stats[0].base_stat,
          hp: data.stats[5].base_stat,
          attack: data.stats[4].base_stat,
          defense: data.stats[3].base_stat
        });
    });
});
return of(pokemonArray);

}

9
  • pokemonStats$: Observable<PokemonStats[]> In this line you clearly states that pokemoStats$ is Observable of PokemonStats[] in type definition Commented Jun 30, 2020 at 8:01
  • And that's why i subscribed to it, to access the array. But why is it showing length: 0 and why can't I access any of the values, even though they are clearly there when console.logging the entire object? Commented Jun 30, 2020 at 8:07
  • The 2nd log entry is interesting as it shows length 0 but it should be 5 from your next log. Can you show the code where the array is actually created? Or a reproducable example. Commented Jun 30, 2020 at 8:10
  • try doing JSON.stringify(stats) and add this json to your question so we can see the raw data in stats. Commented Jun 30, 2020 at 8:11
  • Can you try to remove take(1), and then see whats the result. Commented Jun 30, 2020 at 8:12

1 Answer 1

2

You're returning the new observable with the pokemonArray, which is empty and will be filled async, therefore when you subscribe to getAllPokemonStats it's empty.

Use the forkJoin operator to perform the http requests and map them using the map operator:

getAllPokemonStats(ids: number[]): Observable<PokemonStats[]> {
  return forkJoin(ids.map(id => {
    return this.http.get(`https://pokeapi.co/api/v2/pokemon/${id}`);
  })).pipe(
    map(results => results.map(data => ({
      id: data.id,
      name: data.name,
      speed: data.stats[0].base_stat,
      hp: data.stats[5].base_stat,
      attack: data.stats[4].base_stat,
      defense: data.stats[3].base_stat
    }))),
  );
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.