I have many components that need to download data from a web service. At boot time, I want to show a global progress bar that overlays the complete site. It is possible that several components are loading data at the same time.
Service and Subscriber Service
To synchronize the overall download indicator, I wrote Tools:
import { Observable } from "rxjs/Observable";
import { Observer } from "rxjs/Observer";
import { Injectable } from "@angular/core";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class GlobalLoadingIndicatorService {
private _isLoadingSource = new BehaviorSubject<boolean>(false);
public isLoadingObservable = this._isLoadingSource.asObservable();
public get isLoading(): boolean{
return this._loadingProcessCount > 0;
}
private _loadingProcessCount: number = 0;
public addLoadingProcess(): void{
this._loadingProcessCount += 1;
this._isLoadingSource.next(this.isLoading);
}
public removeLoadingProcess(): void{
this._loadingProcessCount -= 1;
if(this._loadingProcessCount < 0){
throw "Negative _loadingProcessCount is not possible.";
}
this._isLoadingSource.next(this.isLoading);
}
}
In mine AppComponent(this is the root of my application) I saved Observable<boolean>in the property isLoadingObservable:
import { Component, OnDestroy, OnInit } from "@angular/core";
import { GlobalLoadingIndicatorService } from "../Services/GlobalLoadingIndicatorService.js";
import { Subscription } from "rxjs/Subscription";
import { Observable } from "rxjs";
@Component({
selector: "app",
templateUrl: "/Templates/App"
})
export class AppComponent implements OnInit{
constructor(
private _globalLoadingIndicatorService: GlobalLoadingIndicatorService
) { }
public isLoadingObservable: Observable<boolean>;
ngOnInit() {
this.isLoadingObservable = this._globalLoadingIndicatorService.isLoadingObservable;
}
}
In my HTML template, I bind isLoadingObservable:
<div *ngIf="isLoadingObservable | async">Loading...</div>
Add / remove boot processes
Now that I need the global progress bar, I add the service and use the methods:
export class MyComponent implements OnInit, OnDestroy {
constructor(
private _myService: MyService,
private _globalLoadingIndicatorService: GlobalLoadingIndicatorService
) { }
ngOnInit(): void {
this._globalLoadingIndicatorService.addLoadingProcess();
this._myService.getData().subscribe(
x => {
this.userGroups = x;
this.userGroup = x.length > 0 ? x[0].id : null;
this._globalLoadingIndicatorService.removeLoadingProcess();
},
error => {
alert(error);
}
);
}
Problem
In some (not all) components, I get a runtime error:
ExpressionChangedAfterItHasBeenCheckedError: . : '[object Object]'. : 'true'.
, , Angular -Hook-lifecycle.
, : , ExpressionChangedAfterItHasBeenCheckedError
- ChangeDetectorRef.detectChanges setTimeout.
-Loading-Indicator ?
GitHub: ExpressionChangedAfterItHasBeenCheckedError afterViewInit #14748
minuz 4 : . , ?