-1

I have a container something like below

<mat-sidenav-container 
 [ngClass]="{'sidepanel-opened':
 ((isSidePanelVisible$ | async) as isSidePanelVisible) == true }">
</mat-sidenav-container>

Want to use the observable variable in other tags, getting an exception as

Uncaught (in promise): Error: Errors during JIT compilation of template for RiskWorkflowComponent: Parser Error: Missing expected ) at column 53 in [{'sidepanel-opened': ((isSidePanelVisible$ | async) as isSidePanelVisible) == true }] 
San Jaisy
  • 15,327
  • 34
  • 171
  • 290
  • [ngClass]="{'sidepanel-opened': isSidePanelVisible$ | async }" – Eddy Lin Sep 06 '22 at 05:17
  • You will need to use the `as isSidePanelVisible` in combination with `*ngIf` (either on the mat-sidenav-container or e.g. on a surrounding `ng-container`). There it does work. – Gunnar B. Sep 06 '22 at 06:02
  • if I put ng-container on top of mat-sidenav, the mat-sidenav never appears – San Jaisy Sep 06 '22 at 06:12
  • @SanJaisy: That's because when the observable emits `false`, the `*ngIf` resolves to `*ngIf=false` which would not generate the element in the DOM. You could work around it by enclosing the `async` in an object. See my answer for an example. – ruth Sep 06 '22 at 21:36

3 Answers3

1

I usually find it neater to wrap async variables in <ng-container> tags with *ngIf so that they can be reused.

<ng-container 
  *ngIf="{ value: (isSidePanelVisible$ | async) } as isSidePanelVisible"
>
  <mat-sidenav-container 
    [ngClass]="{'sidepanel-opened': isSidePanelVisible.value}"
  >
  </mat-sidenav-container>
</ng-container>

If you'd want to dynamically adjust only one class, you could also use the [class.sidepanel-opened] variant.

<ng-container 
  *ngIf="{ value: (isSidePanelVisible$ | async) } as isSidePanelVisible"
>
  <mat-sidenav-container [class.sidepanel-opened]="isSidePanelVisible.value">
  </mat-sidenav-container>
</ng-container>
  1. This also allows one to resue the emissions from the observable. Note that each async is an individual subscription.
  2. <ng-container> are Angular specific tags that are commented out in the final generated DOM, and so don't lead to additional elements in DOM.
  3. If the async isn't wrapped in an object, i.e. if it's used directly, *ngIf="(isSidePanelVisible$ | async) as isSidePanelVisible", the <ng-container> won't be rendered when the observable emits false since *ngIf directive would resolve to *ngIf=false.
ruth
  • 29,535
  • 4
  • 30
  • 57
0

Try this

<mat-sidenav-container [ngClass]="{'sidepanel-opened': (isSidePanelVisible$ | async) === true }">
</mat-sidenav-container>
rajanbhadauria
  • 445
  • 4
  • 11
0

Try this

<input #isSidePanelVisible [checked]="isSidePanelVisible$ | async" hidden />
<mat-sidenav-container [ngClass]="{ red: isSidePanelVisible.checked }"></mat-sidenav-container>
Eddy Lin
  • 513
  • 2
  • 6