5

I have the following template:

*ngFor="let contact of contacts | async"

Where:

contacts: Observable<any>;

I get this error:

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

Why does ngFor async pipe need Observable<any[]> instead of Observable<T>?

clemtoy
  • 1,681
  • 2
  • 18
  • 30

2 Answers2

3

This is not because of the async pipe.

The contacts Observable emits objects instead of an array and you can't iterate objects with *ngFor. That's what the error message says.

So the problem is with contacts. Have a look at what it really emits.

martin
  • 93,354
  • 25
  • 191
  • 226
  • 1
    I used async to catch emitted objects from Observable. What's the point of getting the whole contact list at once and not item by item otherwise? – clemtoy Jan 19 '18 at 18:02
  • async in combination with the ngFor is not meant to emit item per item. If you want to use so, you can use the scan() operator – kvetis Jan 19 '18 at 21:20
  • @clemtoy kvetis is right. The `async` pipe just shows what you emit. It's not made to "collect" items as you emit them them. That's what `scan` operator is good for. – martin Jan 20 '18 at 17:33
2

ngFor needs to see an iterable of `contacts' (as already stated by @martin), which also means it needs to know the extent of what it's iterating, i.e how many items are you intending to display.

The simplest way forward is to add another property which uses the toArray() operator to the component, and use that in the template.

template

<div *ngFor="let contact of contactsList | async">
  From contactsList: {{contact}}
</div>

component

contactsList = this.contacts.toArray();

However, if you want to display something before contacts observable completes (i.e add to ngFor with each contact emitted), you need a buffering observable.

private buffer = []; 
contactsList = Observable.of(this.buffer); 

ngOnInit() {
  this.contacts.subscribe(contact => {
    this.buffer.push(contact)
  })
}

Demo: StackBlitz

Richard Matsen
  • 20,671
  • 3
  • 43
  • 77