Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

*ngFor com mais de um objeto

Estou tentando criar uma pokedex utilizando a API "PokeAPI", porém ela necessita de várias requisições para pegar os valores completos. Ex: Em uma requisição para o pokemon, ele retorna muitas informações, mas para obter informações adicionais (eu tenho o nome do pokemon, mas preciso da imagem e do índice também), eu tenho que realizar uma segunda requisição, queria saber como posso exibir isso no HTML utilizando *ngFor.

Interface do Pokemon

export interface IPokemon {
  count : number,
  next : string,
  previous : string,
  results : [{
    name: string,
    url: string
  }]
}

Interface das informações do Pokemon:

export interface IPokemon_info {
  id : number,
  name : string,
  base_experience : number,
  height : number,
  weight : number,
  sprites : {
    front_default : string
  },
  types : [{
    slot: number,
    type : {
      name : string,
      url : string
    }
  }],
  abilities : [{
    is_hidden : boolean,
    slot : number,
    ability : {
      name : string,
      url : string
    }
  }],
  moves : [{
    move : {
      name: string,
      url : string
    },
    version_group_details : [{
      level_learned_at : number
    }]
  }],
  stats : [{
    base_stat : number,
    effort : number,
    stat : { name: string}
  }]
}

HTML:

<div class="pokemon-app">
  <div class="pokemons-card" *ngFor="let pokemon of pokemons.results">
    <div routerLink="/Pokemons/{{pokemon.name}}">
    <img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/{{pokemon.url.split('/')[6]}}.png" alt="Imagem do Pokemon" class="imagem-pokemon" />
        <br>
      <label for="pokemon-nome" class="pokemon-nome">
        {{ pokemon.name.toUpperCase() }}
      </label>
    </div>
  </div>
</div>

Eu consegui a imagem por meio de um "meio alternativo", porém a ideia da API é realizar uma segunda requisição na url contida em "results.URL" da interface "IPokemon" e acessar o valor "sprites" da interface "IPokemon_info"

1 resposta
solução!

Olá João, tudo bem contigo?

Para exibir as informações adicionais, como a imagem e o índice do Pokémon, você precisará fazer uma segunda requisição usando a URL fornecida na propriedade url de cada objeto result em pokemons.results.

Aqui está uma maneira de realizar isso no seu HTML:

<div class="pokemon-app">
  <div class="pokemons-card" *ngFor="let pokemon of pokemons.results">
    <div routerLink="/Pokemons/{{pokemon.name}}">
      <ng-container *ngIf="pokemonInfo[pokemon.name]">
        <img src="{{ pokemonInfo[pokemon.name].sprites.front_default }}" alt="Imagem do Pokemon" class="imagem-pokemon" />
        <br>
        <label for="pokemon-nome" class="pokemon-nome">
          {{ pokemon.name.toUpperCase() }}
        </label>
        <br>
        <label for="pokemon-indice" class="pokemon-indice">
          Index: {{ pokemonInfo[pokemon.name].id }}
        </label>
      </ng-container>
    </div>
  </div>
</div>

Você precisará fazer algumas alterações para armazenar as informações adicionais dos Pokémon na variável pokemonInfo. Aqui está um exemplo de como fazer isso:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { IPokemon, IPokemon_info } from './pokemon.interface';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  pokemons!: IPokemon; // Adicione o modificador '!' para indicar que será inicializada posteriormente
  pokemonInfo: { [name: string]: IPokemon_info } = {};

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.http.get<IPokemon>('https://pokeapi.co/api/v2/pokemon').subscribe((data) => {
      this.pokemons = data;
      this.fetchPokemonInfo();
    });
  }

  fetchPokemonInfo() {
    for (const pokemon of this.pokemons.results) {
      this.http.get<IPokemon_info>(pokemon.url).subscribe((data) => {
        this.pokemonInfo[pokemon.name] = data;
      });
    }
  }
}

Agora, o objeto pokemonInfo será preenchido com as informações adicionais de cada Pokémon. No template, usamos pokemonInfo[pokemon.name] para verificar se as informações estão disponíveis antes de exibi-las.

Lembre-se de importar as classes Component, OnInit e HttpClient no seu arquivo TypeScript e injetar o serviço HttpClient no construtor do componente para fazer as requisições HTTP.

Essa abordagem permite que você obtenha as informações adicionais para cada Pokémon e as exiba corretamente no seu HTML usando *ngIf para verificar se os dados estão disponíveis.

Fiz os testes e como você pode ver no Gif deu certo.

E só como recomendação para situações que podem fugir do escopo dos cursos, você levar sua dúvida para o Discord onde outras pessoas também poderão ajudá-lo: https://conteudo.alura.com.br/eventos-no-discord.

Em suma era isso, caso precise eu estarei aqui!

Espero ter ajudado e bons estudos!