-1

As many before me, I have this error :

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

I was trying many solutions like : error display in *ngfor json array object

But nothing works.

  public getInterfaces(): Observable<InterfaceBrief[]> {
    let headers = this.createBasicHeaders();
    let options = new RequestOptions({
      method: 'get',
      headers: headers});
    let url = this.restApi +"/dashboard/list";
    console.log(url);
    return this.http.get(url, options)
      .map(this.extractData)
      .catch(this.handleError);
  }

  private extractData(res: Response) {

    let body = res.json();
    console.log("GOOD");
    return body.data || {};
  }

export class DashboardComponent implements OnInit {

  errorMessage: string;
  interfacesBrief: InterfaceBrief[];

  constructor(private _service: AuthService, private _emotService: EmotClientService) {
  }
  ngOnInit() {
    this.getInterfaces();
  }
  getInterfaces() {
    this._emotService.getInterfaces().subscribe(

      data => this.interfacesBrief = data,
      error => this.errorMessage = <any>error
    );
  }
}

When I changed:

    return body.data || {}; 

to :

return body.data.items || {};

I have error :

Cannot read property 'items' of undefined

ERR :Cannot read property 'data' of undefined

Community
  • 1
  • 1
VANILKA
  • 634
  • 1
  • 13
  • 32

2 Answers2

1

Based on comment, when you console.log your response: Array[2] 0 : Object 1 Object client: "client1" countKO: 3 (...) you clearly are not having a data object in your response, therefore you should just return the response as is.

private extractData(res: Response) {
  let body = res.json();
  return body || []; // here!
}

And when you have received your response, you just iterate that array and display the properties you want, so something like this:

<div *ngFor='let item of interfacesBrief'>
  {{item.client}} - {{item.countKO}} 
  <!-- print whatever else properties you have and want to display -->
</div>
AT82
  • 71,416
  • 24
  • 140
  • 167
  • it works. But could you explain me, why it didn't works like in official documentation ?? Why the data is not present ?? In other request ( post for one item) it was working with body ? – VANILKA Apr 12 '17 at 14:32
  • You don't have an object `data` that would contain the array, in the response you are getting simply an Array. Your response looks something like this: `[{object1 content},{object2 content}]` and not like this: `{data:[{object1 content},{object2 content}]}`. – AT82 Apr 12 '17 at 14:51
  • How the response looks like when it comes, depends solely on what you are sending from the backend and in what structure :) – AT82 Apr 12 '17 at 14:55
  • but my backend never sends {data: ...} but for one item it was working... so ?? – VANILKA Apr 13 '17 at 12:21
  • Well the response you are receiving is set from the backend. Period. There won't be anything magically happening between the frontend and the backend that would change how your response looks like. How the data looks like is set in the backend. Just check the backend, for example, console log the data in the backend before sending it. – AT82 Apr 13 '17 at 12:28
0
  • return only res.json() (why becasue sometimes if data is not fetched proerply than angular will throw error here).

  • try to use elvis operator (safe navigation) in the HTML.

Try this code

  private extractData(res: Response) {

    let body = res.json();
    console.log("GOOD");
    return body || {};
  }

  export class DashboardComponent implements OnInit {
   ...............

  getInterfaces() {
    this._emotService.getInterfaces().subscribe(

      data => {
        this.interfacesBrief = data
        console.log(this.interfacesBrief ,"Without Error")
      },
      error => this.errorMessage = <any>error
    );
  }
}

<div *ngFor='let items of interfacesBrief?.data?.items'>
  {{items}}
</div>
Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215