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.