Andreas Gassmann
Andreas Gassmann

Reputation: 6544

How to handle boolean observables with the async pipe in Angular

I have the following code:

public obs$: Observable<boolean>
<div *ngIf="(obs$ | async) === true || (obs$ | async) === false">
  {{ (obs$ | async) ? 'yes' : 'no' }}
</div>

It works as intended, but the if looks a little verbose.

The problem is that I cannot simply do <div *ngIf="(obs$ | async)">. If I try that, it will work in the case when the observable did not emit a value yet or if the value is true, but it will not work if the value is false, because the if will evaluate to false and the div is not displayed.

I assume the same issue applies if a falsy value is returned, such as an empty string or 0.

Is there a better, easier way of doing that?

Upvotes: 34

Views: 29914

Answers (4)

Hitesh Bariya
Hitesh Bariya

Reputation: 71

You can use "!!" to evalulate to boolean. for example *ngIf = "!!(item$ | async)"

Upvotes: 1

WillyC
WillyC

Reputation: 4705

Here's a way where you can share the subscription and not have to make any custom pipe:

<ng-container *ngIf="{value: obs$ | async} as context">
    {{context.value}}
</ng-container>

The *ngIf will evaluate to true no matter what (I believe) and then you can do your own tests on the value in the context object.

...would be better if they would just implement *ngLet I think!

The thing I like about this solution is that the resulting value is reusable with only the single use of an async pipe and its still pretty concise (even if it isn't perfect).

Upvotes: 60

zhimin
zhimin

Reputation: 3050

I think the most elegant way should be creating a custom BoolPipe , and chain it after the async pipe。

@Pipe({name: 'myBool'})
export class MyBoolPipe implements PipeTransform {
  transform(value: boolean, exponent: string): string {
    return !value ? 'yes' : 'no';
  }
}

and init the obj$ in the constructor of your component or service (don't need null check in your HTML template), then chain it with async pipe like this:

<div>{{ obs$ | async | myBool }}</div>

Upvotes: 0

Sachin Gupta
Sachin Gupta

Reputation: 5301

You can do (obs$ | async) !== null

Upvotes: 18

Related Questions