angularobservablengxs

Use `async` pipe multiple times on same observable


I am using NGXS to update loading state and state is being updated correctly but i am facing one issue that

How to use loading state at multiple places in template?

NGXS selector Looks like as below:

@Select(MyAppState.isLoadingLayouts) loading$: Observable<boolean>;

Now in my template there is a button which needs to be disabled and loader shall be shown in button while dispatching an action. I tried as below but it did not work. Button is not getting disabled.

<button mat-raised-button class="gec-button" (click)="getLayoutsData()" [disabled]="loading">
  <ng-container *ngIf="loading$ | async as loading; else submit">
   <app-progress-bar [diameter]="16"></app-progress-bar>
  </ng-container>
  <ng-template #submit>Submit</ng-template>
</button>

I think we can not use loading$ | async multiple times in template as it triggers multiple async calls.

Is there a way we can achieve this single async pipe?


Solution

  • Sure. You just need to share observable between subscribers:

    public getSharedLoading$() {
      return this.loadging$.pipe(share());
    }
    
    *ngIf="getSharedLoading$ | async as loading; else submit"