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

AngularAsynchronousRxjsObservable

Angular Problem Overview


I have created this interface:

interface IGame {
    name: string;
    description: string;
}

I'm using it as an Observable and passing it as Input to the Component:

@Input() public game: Observable<IGame>;

I can see its value printed using the JSON pipe:

 <h3>{{game | json}}</h3>

When binding to a specific property, nothing is displayed (just an empty string):

 <h3>{{game.name}}</h3>
 <h3>{{game.description}}</h3>

Angular Solutions


Solution 1 - Angular

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 - Angular

##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 - Angular

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLior KooznitsView Question on Stackoverflow
Solution 1 - AngularGünter ZöchbauerView Answer on Stackoverflow
Solution 2 - AngularFlorianView Answer on Stackoverflow
Solution 3 - AngularShayaView Answer on Stackoverflow