Angular Template: How to bind RXJS Observable and read its properties?

Solution 1:

The async pipe does the subscription in view bindings

 <h3>{{(game | async)?.name}}</h3>

The ? is only necessary when null values might be emitted.

Solution 2:

Shortcut for binding multiple properties

Using the *ngIf-As-Syntax factors out the async pipe into a single call (and a single subscription).

  <ng-container *ngIf="( game$ | async ) as game">
    <h3>{{ game.name }}</h3>
    <h3>{{ game.description }}</h3>
  </ng-container>

This only creates one subscription to the observable, it removes the need for ?. and makes working with the template much cleaner.

Note: I renamed the original example observable from game to game$.

Solution 3:

2021 solution: ngrxLet

NgRx 10 presented the @ngrx/component package with the *ngrxLet directive - a convenient way to bind observables in templates.

Usage example:

<ng-container *ngrxLet="observableNumber$ as n">
    <app-number [number]="n">
    </app-number>
</ng-container>

You can even track all the observable notifications:

<ng-container *ngrxLet="observableNumber$; let n; let e = $error, let c = $complete">
    ....
</ng-container>

From the NgRx docs:

The current way of binding an observable to the view looks like that: *ngIf="observableNumber$ | async as n". The problem is *ngIf is also interfering with rendering and in case of a falsy value the component would be hidden. The *ngrxLet directive takes over several things while making it more convenient and safe to work with streams in the template.

An explanatory tutorial about ngrxLet can be found here.