Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
like image 631
Lior Kooznits Avatar asked Jun 07 '16 06:06

Lior Kooznits


3 Answers

The async pipe does the subscription in view bindings

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

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

like image 156
Günter Zöchbauer Avatar answered Oct 16 '22 01:10

Günter Zöchbauer


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

like image 21
Florian Avatar answered Oct 16 '22 02:10

Florian


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.

like image 2
Shaya Avatar answered Oct 16 '22 01:10

Shaya