2

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
Arnaud Denoyelle
  • 29,980
  • 16
  • 92
  • 148
  • 1
    I would guess they mean _"`(observable | async) === false` or `(observable | async) === null` or `(observable | async) === undefined`"_ (i.e. depending on what the value you were checking for actually was), but using the same syntax for two different things makes it ambiguous. – jonrsharpe May 19 '21 at 19:52
  • Seems highly plausible. I will try to submit a PR to propose another text :) – Arnaud Denoyelle May 19 '21 at 19:56

2 Answers2

3

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>
Nicke Manarin
  • 3,026
  • 4
  • 37
  • 79
-1

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

starball
  • 20,030
  • 7
  • 43
  • 238
Sagar Panwar
  • 21
  • 1
  • 11
  • 1
    Your "solution" is wrong, because it will render the if when the value is truthy, but the OP wants to render when the value is falsy. – TmTron May 26 '23 at 06:58