htmlcssangulartypescriptrapidapi

Is there a way I can use *ngFor to iterate over an array of objects


I'm trying to find a solution to show the overall result that I am receiving from the API. Currently only one game and its details can be seen in the app.

My service looks like this:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, map } from 'rxjs';
import { environment } from 'src/environments/environment';

import { Igameschart } from '../interfaces';

interface IgamesData {
  results : [{
name : string,
released : number,
platform : string,
background_image : string,
rating : number
    }]
}

export interface IGamesService{
  getGames(genre:string):Observable<Igameschart>
}
@Injectable({
  providedIn: 'root'
})
export class GamesService implements IGamesService {
  constructor(private httpClient: HttpClient) { }
  getGames(genre:string):
  Observable<Igameschart>{
    return this.httpClient.get<IgamesData>(
      `${environment.baseUrl}api.rawg.io/api/games?` +
      `genres=${genre}&key=${environment.appId}`
    ) .pipe(map(data => this.tarnsformToIgamesData(data)))
  }
private tarnsformToIgamesData(data:IgamesData):
  Igameschart{
    return {
      name: data.results[0].name,
      released: data.results[0].released,
      platform: data.results[0].platform,
      image:data.results[0].background_image,
      rating:data.results[0].rating
    }
  }
}

It is embedded in view in this way:

<div class="container" *ngIf="gamesloaded">
    <div>
        <img [src]='gamesloaded.image' height="249px" width="512em">
    </div>
    <div>
        <div id="gdata">{{gamesloaded.name}}</div>
        <div id="gdata"> {{gamesloaded.released | date:'fullDate'}}</div>
        <div id="gdata"> {{gamesloaded.platform}}</div>
        <div id="gdata">{{gamesloaded.rating}}</div>
    </div>
</div>
<div *ngIf="!gamesloaded">
    <span>No data available</span>
</div>

The code can be found here -> https://stackblitz.com/edit/angular-cbt8ka

I tried looking for solutions to iterate the result but couldn't find one.


Solution

  • you will need to return Igameschart array from tarnsformToIgamesData method of your service so your service will look like

    export interface IGamesService{
      getGames(genre:string):Observable<Igameschart[]>
    }
    @Injectable({
      providedIn: 'root'
    })
    export class GamesService implements IGamesService {
      constructor(private httpClient: HttpClient) { }
      getGames(genre:string):
      Observable<Igameschart[]>{
        return this.httpClient.get<IgamesData>(
          `${environment.baseUrl}api.rawg.io/api/games?` +
          `genres=${genre}&key=${environment.appId}`
        ) .pipe(map(data => this.tarnsformToIgamesData(data)))
      }
    private tarnsformToIgamesData(data:IgamesData):
      Igameschart[]{
        return data.results.map(item=>{return {
          name: item.name,
          released: item.released,
          platform: item.platform,
          image:item.background_image,
          rating:item.rating
        }});
      }
    }
    

    Then your component should be

    gamesloaded: Igameschart[]
      constructor(private gamesService : GamesService) {
      }
      ngOnInit() {
        this.gamesService.getGames('action')
        .subscribe((data) => this.gamesloaded = data)
      }
    

    and your HTML will be

    <div *ngFor='let game of gamesloaded'>
      <div>
        <img [src]='game.image' height="249px" width="512em">
      </div>
      <div id="gdata">{{game.name}}</div>
      <div id="gdata"> {{game.released | date:'fullDate'}}</div>
      <div id="gdata"> {{game.platform}}</div>
      <div id="gdata">{{game.rating}}</div>
    </div>