Souad
Souad

Reputation: 5094

Error NgFor only supports binding to Iterables such as Arrays

Please note that other questions about the same error didn't help because I'm using different way to get the data.

I want to get some data from the API and show them in the page using Angular. The http request will get an array of projects. so here is the projects.component.ts:

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

interface Project {

    alias:Array<string>;
    apps:Array<string>;
    description: string;
    id:string;
    name:string;

}

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


export class ProjectsComponent {



    title:string = "Projects";
    dataProjects: Array<Project>;

    constructor(private httpClient:HttpClient){  }

    getProjects() {
    this.httpClient.get<Array<Project>>("http://company.com/v1/api/projects")
    .subscribe(  data  => { this.dataProjects = data; } )
  }

}

and here is the view in projects.component.html:

  <tbody>
    <tr *ngFor="let proj of dataProjects">
      <td> {{ proj.name }}  </td>
      <td>{{ proj.description }}  </td>
    </tr>
  </tbody>

This is the error I get:

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

How to return an array of Projects ?

EDIT:

Example of output of the API:

{
  "results": [
    {
      "alias": [
        "project"
      ], 
      "apps": [], 
      "description": "Applications natives", 
      "id": "project", 
      "name": "project"
    }
  ]
}

Upvotes: 0

Views: 1985

Answers (4)

Vivek Doshi
Vivek Doshi

Reputation: 58553

DO NOT USE *ngFor="let proj of dataProjects?.results"

Reason : You already have defined the type of dataProjects as Array<Project>

So doing this.dataProjects = data;violates the type , instead of that use this.dataProjects = data. results;


All you need to do is

getProjects() {
    this.httpClient.get<Array<Project>>("http://company.com/v1/api/projects")
    .subscribe(  data  => { this.dataProjects = data.results; } ) // <--- Change here
}

No need to change anything on template side.

Upvotes: 0

ShamPooSham
ShamPooSham

Reputation: 2379

I think the reason why you get this problem is because the variable hasn't been assigned yet when angular tries to iterate through it, so it doesn't have a javascript type yet. You should instead save the observable and use the async pipe in the html-template.

in the typescript:

dataProjects$: Observable<Array<Project>>

getProjects() {
    this.dataProjects$ = this.httpClient.get<Array<Project>>("http://company.com/v1/api/projects")
}

in the html:

<div *ngIf="dataProjects$ | async as dataProjects">
  <tr *ngFor="let proj of dataProjects">
    <td> {{ proj.name }}  </td>
    <td>{{ proj.description }}  </td>
  </tr>
</div>

Upvotes: 1

Souad
Souad

Reputation: 5094

this worked for me:

<tr *ngFor="let proj of dataProjects.results ">
  <td> {{ proj.name }}  </td>
  <td>{{ proj.description }}  </td>
</tr>

Upvotes: 0

Antoine V
Antoine V

Reputation: 7204

I think your method getProjects is never called. That means dataProjects is null

Try

<tr *ngFor="let proj of dataProjects?.results">
      <td> {{ proj.name }}  </td>
      <td>{{ proj.description }}  </td>
    </tr>

Upvotes: 2

Related Questions