I tend to combine *ngIf and async like so:
My component will have an Observable (or in your case a Promise), with a variable name that ends with $. This naming pattern comes from the observable naming guide here
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
//Create a subject with an initial value
//Keep the subject private so only this component may emit value
private _mySubject = new BehaviorSubject<any>('initial value!');
//Expose the observable as a public variable
//This allows the template to listen for values
get myObservable$() {
return this._mySubject.asObservable();
}
//helpers for demo!
emitNull() {
this._mySubject.next(null);
}
emitUndefined() {
this._mySubject.next(undefined);
}
emitNumber(number) {
this._mySubject.next(number);
}
emitText(text) {
console.log(text);
this._mySubject.next(text);
}
}
Then my template:
<div>
<button (click)="emitNull()">Emit Null</button>
</div>
<div>
<button (click)="emitUndefined()">Emit Undefined</button>
</div>
<div>
<button (click)="emitNumber(num.value)">Emit Number</button>
<input type="number" #num value="42" />
</div>
<div>
<button (click)="emitText(txt.value)">Emit String</button>
<input type="text" #txt value="foo" />
</div>
<br />
<h1>Value:</h1>
<ng-container *ngIf="myObservable$ | async as value; else other">
<div>{{ value }}</div>
</ng-container
>
<ng-template #other>
<div>The value was null, undefined or empty string</div>
</ng-template>
The template essentially reads as:
if(somevalue)
render a div displaying the value
else
render a div with text "The value was null..."
The key thing is that async is a pipe. A pipe always transforms some input. In this case, we're passing in an observable (or a promise) and getting some output.
So putting it all together, the template is:
- Subscribing to the observable (or
then'ing in the case of a promise),
- Outputting a something whenever a new value is emitted, capturing it in a variable named
value
- Performing the
if check on value
- Conditionally rendering the stuff inside
ng-container or using the template marked with #other
Here's a stackblitz demonstrating the above!
As an aside, I recognize my example is using Observable instead of Promises. As I understand it, they essentially work the same. However, I strongly recommend using Observables over Promises in any Angular application. Observables are far more flexible and I think you'll run into far less confusing behavior.
(this.status)is completed with the valuestable, Your promise is completed after 2.5sec (via SetTimeout)