Full StackBlitz example: https://stackblitz.com/edit/angular8-async-pipe
There are three identical components in app component template:
<app-loader></app-loader>
<app-progress></app-progress>
<app-spinner></app-spinner>
Every component dispatches it's own NgRx action, which fires an Http request using NgRx effects and waits for its completion:
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { ActionsService } from '../../../services/actions.service';
import * as MockyActions from '../../actions/mocky.actions';
@Component({
selector: 'app-spinner',
templateUrl: './spinner.component.html'
})
export class SpinnerComponent implements OnInit {
progress$: Observable<boolean>;
constructor (
private store: Store<any>,
private actionsService: ActionsService) {}
ngOnInit() {
this.progress$ = this.actionsService
.isInProgress(MockyActions.GetMockySpinner)
.pipe(
map(({status}) => status),
tap((status) => console.log('GetMockySpinner: ', status))
);
this.store.dispatch(MockyActions.GetMockySpinner());
}
}
In every component using Async Pipe I want to show spinner while Http request is in progress:
<div class="text-center" *ngIf="!(progress$ | async); else progress">
Spinner
</div>
<ng-template #progress>
<div class="text-center">
<span class="spinner spinner-sm"></span>
</div>
</ng-template>
But only spinner in <app-spinner></app-spinner> component is displaying during Http request progress in this case. And if the sequence of components in app component template changed:
<app-loader></app-loader>
<app-progress></app-progress>
<app-spinner></app-spinner>
<app-loader></app-loader>
Spinner in <app-loader></app-loader> component is displaying during Http request progress in this case. So only last component in template works as expected.
So what's changed with Async Pipe in Angular 8 or what I'm doing wrong?
Full StackBlitz example: https://stackblitz.com/edit/angular8-async-pipe