Error While Consuming Api at Angular

Asked

Viewed 259 times

1

Good Afternoon I’m consuming an api (Pokemon), But it doesn’t work,

Pokelistgemcomponent.html:6 ERROR Error: Cannot find a differ supporting Object '[Object Object]' of type 'Object'. Ngfor only Supports Binding to Iterables such as Arrays.

My Component :

import { HttpClient } from '@angular/common/http';
import { ApiService } from './../api.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-poke-listagem',
  templateUrl: './poke-listagem.component.html',
  styleUrls: ['./poke-listagem.component.css']
})

export class PokeListagemComponent implements OnInit {


  pokemon: Array<any>;

  constructor(private apiService: ApiService) { }

  ngOnInit() {
    this.listar();
  }

  listar() {
    this.apiService.listar()
      .subscribe(dados => this.pokemon = dados);
  }

}

My template :

<ul>
<li *ngFor="let p of pokemon" >
  {{p.url}}  {{p.name}}
</li>
</ul>

Service:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class ApiService {


  PokeUrl='http://pokeapi.salestock.net/api/v2/pokemon'; 
  constructor(private http: HttpClient) { }

  listar() { //lista os filmes
    return this.http.get<any[]>(`${this.PokeUrl}`);
  }



}

4 answers

1

As much as the subscribe is a kind of return of your Listar(), I recommend that in this context do not use the subscribe but directly the Observable with the pipe Async.

pokemon$: Observable<any>;

In your List method, use:

listar() {
    this.pokemon$ = this.apiService.listar()
  }

In the DOM, do:

<ul>
<li *ngFor="let p of pokemon$ | async" >
  {{p.url}}  {{p.name}}
</li>
</ul>

Is a best practice.

1

Tries to initialize the variable

pokemon: Pokemon[]= []

or

 pokemon: any[]= []

1

the return of the api being used returns an object and the ngFor supports only whole objects like arrays

Below is an example of the url return http://pokeapi.salestock.net/api/v2/pokemon

{
    "count": 811,
    "previous": null,
    "results": [
        {
            "url": "http://pokeapi.salestock.net/api/v2/pokemon/1/",
            "name": "bulbasaur"
        },
       // ....
        {
            "url": "http://pokeapi.salestock.net/api/v2/pokemon/20/",
            "name": "raticate"
        }
    ],
    "next": "http://pokeapi.salestock.net/api/v2/pokemon/?offset=20"
}

in this case the function list should be rewritten

listar() {
 this.apiService.listar()
  .subscribe(dados => this.pokemon = dados.results);
}

0

The problem is because the variable pokemon is undefined during the rendering of your template. Note that although you trigger your API to fill this variable, completing the request takes a certain amount of time. Before completing the request, the template has already been rendered and generated the problem because the variable is still undefined. See that it is an asynchronous process.

To solve the problem just initialize your variable or apply a *ngIf to check whether the variable pokemon has already been filled:

// Inicialize sua variável com um Array vazio
pokemon = [];

or:

<ul *ngIf="pokemon">
    <li *ngFor="let p of pokemon" >
        {{p.url}}  {{p.name}}
    </li>
</ul>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.