0
votes

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"
    }
  ]
}
4
When I use | keyvalue I get empty dataSouad
try data.json()Chellappan வ
Where to put data.json() ?Souad
What is the output of http://company.com/v1/api/projects ?Vivek Doshi
check the update please. thank youSouad

4 Answers

2
votes

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>
1
votes

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>
0
votes

this worked for me:

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

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.