angulartypescriptriot-games-api

Riot API With Angular 2


I trying to use the Riot API for Champions in this code

--Service

@Injectable()
export class ChampionService {

private riotUrl = 'https://br1.api.riotgames.com/lol/static-
data/v3/champions?api_key=myApiKey';
constructor(private _http: Http) { }
getChampion(): Observable<Champion[]> {
    return this._http.get(this.riotUrl)
        .map((res:Response) => <Champion[]>[res.json()])
        .do(data => console.log(JSON.stringify(data)));
}}

-- Component

export class ChampionListComponent{
errorMessage: string;
champions: Champion[];
constructor(private _ChampionService: ChampionService){}
ngOnInit():void{
  this._ChampionService.getChampion()
            .subscribe(champions => this.champions = champions,
                       error => this.errorMessage = <any>error);}

--HTML

<table class="table">
            <thead>
                <tr>
                    <th>Id</th>
                    <th>Name</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor='let champion of champions'>
                    <td>{{champion.id}}</td>
                    <td>{{champion.name}}</td>
                </tr>
            </tbody>
        </table>

In the console that's appears correctly.. but nothing happen with my table

--- My Console Show This Angular is running in the development mode. Call enableProdMode() to enable the production mode. champion-list.service.ts:18 [{"type":"champion","version":"7.8.1","data":{"Jax":{"id":24,"key":"Jax","name":"Jax","title":"o Grão-Mestre das Armas"},"Sona":{"id":37,"key":"Sona","name":"Sona","title":"a Mestra das Cordas"},"Tristana":{"id":18,"key":"Tristana","name":"Tristana","title":"a Artilheira Yordle"},"Varus":{"id":110,"key":"Varus","name":"Varus","title":"a Flecha da Vingança"},"Fiora":{"id":114,"key":"Fiora","name":"Fiora","title":"a Grande Duelista"},"Singed":{"id":27,"key":"Singed","name":"Singed","title":"o Químico Louco"},"TahmKench":{"id":223,"key":"TahmKench","name":"Tahm Kench","title":"o Rei do Rio"},"Leblanc":{"id":7,"key":"Leblanc","name":"LeBlanc","title":"a Farsante"},"Thresh":{"id":412,"key":"Thresh","name":"Thresh","title":"o Guardião das Correntes"},"Karma":{"id":43,"key":"Karma","name":"Karma","title":"a Iluminada"},"Jhin":{"id":202,"key":"Jhin","name":"Jhin","title":"o Virtuoso"},"Rumble":{"id":68,"key":"Rumble","name":"Rumble","title":"a Ameaça Mecânica"},"Udyr":{"id":77,"key":"Udyr","name":"Udyr","title":"o Andarilho Espiritual"},"LeeSin":{"id":64,"key":"LeeSin","name":"Lee Sin","title":"o Monge Cego"},"Yorick":{"id":83,"key":"Yorick","name":"Yorick","title":"Pastor de Almas"},"Kassadin":{"id":38,"key":"Kassadin","name":"Kassadin","title":"o Andarilho do Vazio"},"Sivir":{"id":15,"key":"Sivir","name":"Sivir","title":"a Mestra da Batalha"},"MissFortune":{"id":21,"key":"MissFortune","name":"Miss Fortune","title":"a Caçadora de Recompensas"}...

someone can help me ? Sorry for the long post


Solution

  • Even though you are setting your response in an array:

    .map((res:Response) => <Champion[]>[res.json()])
    

    This still means that your array just contains one object, that contains objects (which you want to iterate). So first let's remove the assignment to an array, and instead step into the JSON and extract the object that contains your objects that you want:

    .map((res:Response) => res.json().data)
    

    This means you end up with an object with your objects. Since object cannot be iterated, we need to use a pipe:

    @Pipe({ name: 'keys',  pure: false })
    export class KeysPipe implements PipeTransform {
        transform(value: any, args?: any[]): any[] {
            // create instance vars to store keys and final output
            let keyArr: any[] = Object.keys(value),
                dataArr = [];
    
            // loop through the object,
            // pushing values to the return array
            keyArr.forEach((key: any) => {
                dataArr.push(value[key]);
            });
    
            // return the resulting array
            return dataArr;
        }
    }
    

    Then apply that pipe in your template:

    <tr *ngFor='let champion of champions | keys'>
      <td>{{champion.id}}</td>
      <td>{{champion.name}}</td>
    </tr>
    

    That should do the trick! :)

    As a sidenote, this means your response is not an Array of Champion, so assigning it <Champion[]> is inaccurate. However your interface is built, you need to make the appropriate changes.

    Demo