Async pipes should not be negated

1.8k Views Asked by At

I migrated from TSLint to ESLint following the guide. Now, I get this error message :

Async pipes should not be negated. Use (observable | async) === (false | null | undefined) to check its value instead

And here is the given explanation :

Angular’s async pipes emit null initially, prior to the observable emitting any values, or the promise resolving. This can cause negations, like *ngIf=”!(myConditional | async)” to thrash the layout and cause expensive side-effects like firing off XHR requests for a component which should not be shown.

But I don't understand the proposed solution, particularly the bitwise OR : false | null | undefined. When I try to write (false | null | undefined) in a template, Angular seems to consider null and undefined as pipes (which seems legit) and throws an error message. Even outside of an html template, this bitwise OR just returns 0 so, what is the point ? I also tried false || null || undefined but it is actually equivalent to undefined

Did I miss something ? Or is the error message misleading ? How should I write it then ?

The best I have is this but it is pretty ugly :

(observable | async) === false || (observable | async) === undefined
2

There are 2 best solutions below

0
On

As another way to compare the values from the observable, you can create your own pipes:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'isFalsy',
  pure: false,
})
export class IsFalsyPipe implements PipeTransform {
  transform(value: any): any {
    return value ? false : true;
  }
}

Import in your module and then compare it like this:

<div *ngIf="observable$ | async | isFalsy"></div>
1
On

Issue is:

Negating an async pipe in an *ngIf thrashes the layout because the pipe emits null immediately before checking the condition. This can lead cause unnecessary rendering work and trigger component events which cause XHR's or other work to be done that shouldn't be needed.

Solution :

<div *ngIf="!!(observable$ | async)"></div>

Here is the detail you can explore more : https://github.com/angular/angular/issues/44867