Assigning a piped async result to a variable in an Angular view

If you have an Observable<x> in your component you might find yourself doing something like this

{{ ( source$ | async)?.property1 }}
{{ ( source$ | async)?.property2 }}

This will subscribe to the source$ observable more than once. A commonly used technique to avoid this is to assign the result of the async into a view variable, like so:

<ng-container ngif=”source$ | async as source”>
  {{ source?.property1 }}
  {{ source?.property2 }}

But if you have other UI elements within that ng-container that you want to be displayed whether or not source$ has emitted a value then you might not like the fact that a portion of your UI is excluded until the observable emits a value or when the observable emits a falsey value. If that is the cast, you can try this little trick.

<ng-container ngif=”(source$ | async) || {} as source”>
  {{ source.property1 }}
  {{ source.property2 }}

We utilise *ngIf to assign the emitted source$ value to the source variable, but default it to an empty object to ensure it always returns true. This uses only a single subscription to source$, and ensures our UI is visible whether source$ has already emitted a value or not.


Leave a Reply

Your email address will not be published. Required fields are marked *