I've got 3 components:
c1 contains c2 and c3
c2 contains a checkbox. When checkbox is toggled I fire an event to an Output variable.
<input type="checkbox" [checked]="displayAxialMap" (click)="onToggleAxialMap()" />
and in component:
onToggleAxialMap() {
this.displayAxialMap = !this.displayAxialMap;
this.toggleMap.emit(<Map>{ display: this.displayAxialMap, mapType: MapType.AXIALMAP, loading: true });
}
in c1 I've got a behaviourSubject called displayMap
<c2 (toggleMap)="displayMap.next($event)"></c2>
in c1 I also pass displayMap value to c3
<c3 [displayMap]="displayMap"></c3>
c3 in ngOnInit() I do this:
this.displayMap.subscribe(map => {
this.loading = map.loading;
this.drawAxialMapCanvas();
this.loading = false;
})
this.loading is initialized to false.
Everything is working (so there is no problem in passing data trough components). But this.drawAxialMapCanvas(); is a function that take long time to complete (3-4 seconds) and I see two strage behaviours:
<... *ngIf"loading">Loading...
It never shows up... It takes only the last value!
It seems that my UI is updated only when this.drawAxialMapCanvas() is completed. What am I do wrong?
For the 1) it's normal, javascript is single thread so everything is simply blocked by this.drawAxialMapCanvas
2) You try to show a loading message but you have here the same probleme, angular is not updating since the the.drawAxialMap is not finish and block the thread (4 secondes is really long for a non asynchrone loading).
You can first the make the this.drawAxialMap running in the next event loop by doing :
this.displayMap.subscribe(map => {
this.loading = map.loading;
setTimeout( () => {
this.drawAxialMapCanvas();
this.loading = false;
)};
});
It will let the time to refresh (checkbox, message..)
Anyway you should do something about this.drawAxialMapCanvas(); I never have faced this situation but perhaps use a worker or loading part by part by using something like [ setTimeout() / setImmediate()] to let the UI the time to manage user event etc...