I have a problem with Angular and Promises I don't understand.
This is my html:
<div>Is Ready? {{isReady}}</div>
<div *ngIf="isReady">Show this</div>
<div *ngIf="!isReady">Show that</div>
This is my TS file:
isReady: boolean = false;
constructor(
private myService: MyService){
await this.giveMeSlowData();
}
async giveMeSlowData() : Promise<void>{
console.log(await this.myService.getResult());
this.isReady = await this.myService.getResult();
}
Usually everything in this {{}} in HTML changes as soon as the variable in TS file. But not now. I can see console log after 5-6 seconds, but the HTML doesn't change. Why?
Thanks anyone!
There are a few reasons why this never completes yet you get your console log.
You have an async
method that never returns anything. That leaves the Promise
hanging forever. Since await
is called on the hung Promise
in the constructor, the component will never finish initializing. You can test this by adding a log statement in an ngOnInit
.
I would strong encourage you to switch to using an Observable as that is the standard practice in Angular world. A lot of things with component destruction is handled automatically for you that way. You can even do this without needing to change any logic of MyService
which can be convenient if that must remain as a Promise
-based class.
All initialization logic should be handled in an ngOnInit
method, not in the constructor.
I would encourage you to switch to using the async
pipe in the template on all of this.
Here's how that all would come together.
slow-data.component.ts
:
isReady: Subject<boolean> = new BehaviorSubject(false);
constructor(
private myService: MyService,
) {
}
ngOnInit(): void {
giveMeSlowData();
}
giveMeSlowData(): void {
from(this.myService.getResult()).subscribe(isReady);
}
slow-data.component.html
<div>Is Ready? {{isReady | async}}</div>
<div *ngIf="isReady | async">Show this</div>
<div *ngIf="!(isReady | async)">Show that</div>