Inias
Inias

Reputation: 37

angular4 Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays

Stuck with error = Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

Service code =

`export class PokemonServiceService {
    constructor(private http: HttpClient) { }

    get getCards(): Observable<ICards[]>{
    return this.http.get<ICards[]>('https://api.pokemontcg.io/v1/cards?')
        }
    }
 export interface Ability {
  name: string;
  text: string;
  type: string;
   }
export interface Attack {
  cost: string[];
  name: string;
  text: string;
  damage: string;
  convertedEnergyCost: number;
}
export interface Weakness {
  type: string;
  value: string;
}
export interface Resistance {
  type: string;
  value: string;
}
export interface Card {
  id: string;
  name: string;
  nationalPokedexNumber: number;
  imageUrl: string;
  imageUrlHiRes: string;
  types: string[];
  supertype: string;
   subtype: string;
   ability: Ability;
   hp: string;
   retreatCost: string[];
   convertedRetreatCost: number;
   number: string;
  artist: string;
  rarity: string;
  series: string;
  set: string;
  setCode: string;
  text: string[];
  attacks: Attack[];
  weaknesses: Weakness[];
  resistances: Resistance[];
  evolvesFrom: string;
 }
export interface ICards {
  cards: Card[];
}

Component code =

`export class MainActivityComponent implements OnInit {
 PokemonData: ICards[];
 constructor(private service: PokemonServiceService ){}
 ngOnInit(): void {
 this.service.getCards.subscribe(data => this.PokemonData = data);      
            }



}`

Html code =

`<div class="card" *ngIf="PokemonData">
<div class="card-header">Pokemon</div>
<div class="card-block">
  <table class="table table-hover">
      <thead>
          <tr>
              <th>Naam</th>
              <th>id</th>
              <th>hp</th>
              <th>pokedexnumer</th>

          </tr>
      </thead>
      <tbody>
          <tr *ngFor="let d of PokemonData">      <!-- | async -->
              <td>{{d.name}}</td>
              <td>{{d.id}}</td>
              <td>{{d.hp}}</td>
              <td>{{d.nationalPokedexNumber}}</td>
          </tr>
      </tbody>
  </table>

)`

and if I use this in my component

ngOnInit(): void {
this.service.getCards()
            .subscribe(data => {
              console.log(data);
            })

then i get the data from the api (cards) , but if i try to sort them in a list i get this error = Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.

Upvotes: 1

Views: 2771

Answers (2)

Desu
Desu

Reputation: 900

What is your the output on logging the data? Maybe it's wrapped like this, try to unwrap it first.

The response

[{someData},{someData}]

Unwrap

function readData < T > (xhrData: any) {

  try {


    var len = Object.keys(xhrData).length;

    var temp: Array < T > = [];

    for (var x = 0; x < len; x++) {
      //unwrap it and transfer it to an array -
      temp[temp.length] = xhrData[x]; //example only
    }
  } catch (e) {
    return [];
  }


  return temp;
}

I like to wrap my reader on a try catch block to also catch error responses from the server if its not a JSON.

Upvotes: 0

user184994
user184994

Reputation: 18271

The API doesn't return an array, it returns an object with a cards property.

Change your service, like so:

get getCards(): Observable<ICards>{
    return this.http.get<ICards>('https://api.pokemontcg.io/v1/cards?')
}

You component like so:

PokemonData: ICards;

And your template like so:

<tr *ngFor="let d of PokemonData.cards">

Upvotes: 1

Related Questions