Angular async pipe and object property
The error is surprisingly accurate as the *ngIf
directive expects true
or false
and uses the resulting expression to determine whether or not to render the HTML
element in the DOM.
EXCEPTION: Invalid argument 'true' for pipe 'AsyncPipe' in [!user$.anonymouse | async in SettingsPage@27:22]
The expression you have is user$.anonymouse
which evaluates as truthy, but unfortunately you cannot use the async
pipe with this directive. The async
pipe "transforms" (also known as "pipes") the input exposing the resulting output within the scope of the *ngFor
directive for example.
The pipe expects one of three possible types, defined below (detailed about AsyncPipe):
transform(obj: Observable<any>| Promise<any>| EventEmitter<any>)
Is there any way how to solve this?
Yes, you can either use it as it was designed. For example in an *ngFor
directive:
<ion-item *ngFor="(user$ | async)?.anonymouse">
<ion-label>Login</ion-label>
</ion-item>
Or you could remove the piping altogether as it's not needed for the *ngIf
directive:
<ion-item *ngIf="user$.anonymouse">
<ion-label>Login</ion-label>
</ion-item>
As stated in the comments by @Sean, your *ngIf
statement should be based on the resulted object property anonymouse
of the user$
object that is returned. As such:
<ion-item *ngIf="(user$ | async)?.anonymouse">
<ion-label>Login</ion-label>
</ion-item>
This worked for me and here is an example of how to use the results from the pipe below:
Component
message$: Observable<{message: string}>;
private messages = [
{message: 'You are my hero!'},
{message: 'You are the best hero!'},
{message: 'Will you be my hero?'}
];
constructor() { this.resend(); }
resend() {
this.message$ = Observable.interval(500)
.map(i => this.messages[i])
.take(this.messages.length);
}
View
<h2>Async Hero Message and AsyncPipe</h2>
<p>Message: {{ (message$ | async)?.message }}</p>
<button (click)="resend()">Resend</button>`
A working example can be found here.