I have the following in my component template:
<div *ngIf="user$ | async as user>...</div>
Within the above div
I would like to use the async pipe to subscribe to another observable only once, and use it just like user
above throughout the template. So for instance, would something like this be possible:
<ng-template *ngIf="language$ | async as language>
<div *ngIf=" user$ | async as user>
<p>All template code that would use both {{user}} and {{language}} would go in between</p>
</div>
</ng-template>
Or can this even be combined in one statement?
You can use object as variable:
<div *ngIf="{ language: language$ | async, user: user$ | async } as userLanguage">
<b>{{userLanguage.language}}</b> and <b>{{userLanguage.user}}</b>
</div>
Plunker Example
See also
- How to declare a variable in a template in Angular2
The problem with using "object as variable" is that it doesn't have the same behavior as the code in the question (plus it's a mild abuse of *ngIf to have it always evaluate to true). To get the desired behavior you need:
<div *ngIf="{ language: language$ | async, user: user$ | async } as userLanguage">
<ng-container *ngIf="userLanguage.language && userLanguage.user">
<b>{{userLanguage.language}}</b> and <b>{{userLanguage.user}}</b>
</ng-container>
</div>
While the other solutions work, they slightly abuse the purpose of ngIf
which should only optionally render a template. I've written an ngxInit
directive that always renders even if the expression result is "falsy".
<div *ngxInit="{ language: language$ | async, user: user$ | async } as userLanguage">
<!-- content -->
</div>
see https://github.com/amitport/ngx-init