Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Observable isn't triggered by async pipe

Consider this simple snippet of angular2/rxjs/typescript

  public rooms: Observable<Room[]>;      

  constructor ( ... ) {

    this.rooms = this.inspectShipSubject
      .do(() => console.log('foo'))
      .switchMap(ship => this.roomByShipService.getRoomsByShip(ship));

    //this.rooms.subscribe(); // <-- [1]
  }

Here's the template:

<some-component *ngFor="let room of rooms | async" [room]="room"></some-component>

It doesn't work ('foo' is not printed and no data shows) unless I uncomment the line indicated [1]. Why doesn't the template trigger the observable to execute automatically?

Is there a better way than to use a blank subscribe?

like image 407
kvanbere Avatar asked Jun 22 '26 17:06

kvanbere


1 Answers

OK, I'm not sure why, but the trick is to use BehaviourSubject instead of Subject on this.inspectShipSubject.

This works nicely and is triggered properly by the template.

  public rooms$: Observable<Room[]>;

  private inspectShipSubject: BehaviorSubject<Ship> = new BehaviorSubject<Ship>(null);

  constructor(
    ...
  ) { }

  ngOnInit() {
    this.rooms$ = this.inspectShipSubject.switchMap(ship => this.roomByShipService.getRoomsByShip(ship));
  }

  @Input()
  set ship(ship: Ship) {
    this.inspectShipSubject.next(ship);
  }

  get ship(): Ship {
    return this.inspectShipSubject.getValue();
  }

And the template:

<some-component *ngFor="let room of (rooms | async)" [room]="room"></some-component>
like image 88
kvanbere Avatar answered Jun 24 '26 07:06

kvanbere