Sammy
Sammy

Reputation: 3707

Putting two async subscriptions in one Angular *ngIf statement

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?

Upvotes: 27

Views: 6981

Answers (3)

Amit Portnoy
Amit Portnoy

Reputation: 6336

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

Upvotes: 4

yurzui
yurzui

Reputation: 214295

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

Upvotes: 29

kayjtea
kayjtea

Reputation: 3129

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>

Upvotes: 14

Related Questions