Issue
For the status
property declared and populated like below:
public status:Promise<String>;
constructor() {
this.status = this.getStatus();
}
public getStatus():Promise<String>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('stable');
},2500);
});
}
could somebody explain how the below async
pipe works?
<span *ngIf="status|async">
{{ status|async }}
</span>
Solution
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 onvalue
- 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.
Answered By - spots
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.