0
votes

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:

  1. the checkbox in c2 change to checked only when this.drawAxialMapCanvas() completes.
  2. the local variable "loading" inside c3 (If I debug code) correcly pass from false, to true to false again. But if I put that variable in the template:

<... *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?

1
can you create a stackbliz please - devpato

1 Answers

1
votes

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...