3

AsyncPipe works with BehaviorSubject, but I don't want to initialize my service with empty data, for this reason I use Subject intead.

The problem is NgFor and asyncPipe doesn't work with Subject, is it an issue?

This works:

Component:

export class AppComponent {
  foo = new BehaviorSubject<Array<number>>([1,2,3]);

  getFoo(){
     return this.foo.asObservable();
  }
}

Template

<span *ngFor="let e of foo.asObservable() | async">{{e}}</span>

This NOT WORKS:

Component

export class AppComponent {
  foo = new Subject<Array<number>>();

  constructor(){
     setTimeout(() => {
          this.foo.next([1,2,3]);
     }, 3000);
  }

  getFoo(){
     return this.foo.asObservable();
  }
}

Template

<span *ngFor="let e of foo.getFoo() | async">{{e}}</span>
Serginho
  • 7,291
  • 2
  • 27
  • 52

1 Answers1

5

The problem here is calling a method from my template - this means every time change detection runs, I'm calling your getFoo() function, which returns a new instance of the observable, which resets the async pipe.

So, the code fails whether you call getFoo() in the NgFor.

Solucion, create an observable variable in the component.

Serginho
  • 7,291
  • 2
  • 27
  • 52
  • You're not calling `getFoo()` anywhere in your template. – martin Oct 07 '16 at 08:21
  • Sorry, In the wrong case I created the `getFoo()` but I forgot to call it in the view. I just update it now. Anyway, same behavior cause I was calling `asObservable()`. Thanks. – Serginho Oct 07 '16 at 08:25
  • could you elaborate on "create an observable variable in the component?" I have a variable like this `private user: Observable;` in my component. But... this didn't work! Do you have to initialize the observable or something? – Eric Huang Jun 27 '18 at 13:43