Lior Kooznits
Lior Kooznits

Reputation: 743

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

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>

Upvotes: 60

Views: 35844

Answers (3)

Shaya
Shaya

Reputation: 2932

The modern 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.

Upvotes: 5

Florian
Florian

Reputation: 471

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$.

Upvotes: 24

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657318

The async pipe does the subscription in view bindings

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

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

Upvotes: 85

Related Questions