0

I tried to use async pipe and ngFor directive in Angular 4.4. It works fine but I got weird error message in console:

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

<table>
  <tbody>
  <tr *ngFor="let event of events | async">
  </tr>
  </tbody>
 </table>


export class EventsComponent {

  events: Observable<Array<Event>>;

  constructor(private eventService: EventService) {
      this.events = this.eventService.findAll();
  }
}

Please advise

Sergiy
  • 1,854
  • 4
  • 22
  • 34
  • `*ngFor` only iterates arrays, but doesn't support iterating objects. You can use a pipe like shown in https://stackoverflow.com/questions/41396435/how-to-iterate-object-object-using-ngfor-in-angular-2/41396558#41396558 – Günter Zöchbauer Sep 30 '17 at 07:02
  • 2
    The events actually emitted by the observable returned by findAll() seem to be objects, not arrays. Check what you really return from that method (at runtime). – JB Nizet Sep 30 '17 at 07:05
  • Well, findAll method returns Observable of array. So ngFor actually displays returned data. The only issue is error message in the console. – Sergiy Sep 30 '17 at 07:36
  • Here's signature of findAll function: findAll(): Observable> { return this.http.get>(this._baseUrl); } – Sergiy Sep 30 '17 at 07:37
  • 1
    The signature is irrelevant. TypeScript only checks types at compile time. It has no way to ensure that your backend service actually returns JSON representing an array of events. So it trusts you on that. You need to check what it actually returns **at runtime**. – JB Nizet Sep 30 '17 at 13:15

1 Answers1

1

I reproduced your error in a Plunker :

https://plnkr.co/edit/KpEnf2KOm8XJXurBTjFQ?p=preview

To create the error, I made my service method return an object instead of the expected array :

findAll(): Observable<Array<string>> {
  return Observable.of({ data: ['Francis', 'Emilie', 'Diego'] });
}

Then, I called the method from the component :

@Component({
  selector: 'my-app',
  template: `
    <div>
      <ul>
        <li *ngFor="let name of names | async">{{ name }}</li>
      </ul>
    </div>
  `,
})
export class App implements OnInit {

  names: string;

  constructor(private eventService: EventService) { }

  ngOnInit(): void {
    this.findAll();
  }

  findAll(): void {
    this.names = this.eventService.findAll();
  }
}

And I got

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

As already said JB Nizet in a comment below your post, you should check what you really return from the findAll method.

Arpp
  • 301
  • 1
  • 11
  • Thank you, Arpp. It turned out that I had two *ngFor on page(for desktop and mobile version). Second *ngFor missed async pipe so it was hidden but still raised an error. – Sergiy Oct 03 '17 at 11:45