Miguel Moura
Miguel Moura

Reputation: 39364

NgIf and zero: Why is the template not being rendered?

I have the following observable on and Angular component:

count$: Observable<number>;

this.count$ = this.getCount();

By using the following I get the value 0 (Zero);

this.count$.subscribe(x => console.log(x));

On the template I have:

<a routerLink="/dash" *ngIf="(count$ | async)">
  <ng-container *ngIf="count$ | async as count">
    Count: {{count}}
  </ng-container>
</a> 

If count$ is 1 I get Count: 1 but if count$ is 0 the content Count: 0 is not even rendered.

Any idea why?

Upvotes: 4

Views: 3681

Answers (5)

TCH
TCH

Reputation: 594

@Jota.toledo answer is correct, *ngIf treats 0 as a falsy value and does not render it.
In this case, I often use the LetDirective as a workaround.

    import { LetDirective } from '@ngrx/component';
    <a routerLink="/dash" *ngrxLet="count$ | async as count">
        Count: {{count}}
    </a> 

Since Angular 18.1 you can also use @let

    @let count = count$ | async;
    <a routerLink="/dash" *ngIf="count != null">
        Count: {{count}}
    </a> 

Upvotes: 0

David Agui&#241;aga
David Agui&#241;aga

Reputation: 1

In these cases:

    if (false)
    if (null)
    if (undefined)
    if (0)
    if (NaN)
    if ('')
    if ("")
    if (``)

These are all falsy as stated above, here is my suggestion: By using a pipe(map()) to convert it to string, that way '0' is not falsy and it can still be used with number pipe, etc.

Hope this helps some else.

Upvotes: 0

Patrick
Patrick

Reputation: 1291

In case anyone is looking for a workaround, this so stupid but it works:

   <ng-container *ngIf="{ len: count$ | async } as ctx">
      <ng-container *ngIf="ctx.len !== null"        
          {{ ctx.len }} 
       </ng-container>
   </ng-container>

Explanation:

  1. Capture count as len inside of an object called ctx
  2. Because *ngIf is now looking at an object, instead of the value, it will evaluate as truthy and render the ng-container
  3. Now we check whether we got an actual value or not with ctx.len !== null
  4. We can access the value using ctx.len

Upvotes: 14

Jota.Toledo
Jota.Toledo

Reputation: 28434

As discussed in this issue, this is the expected behavior. NgIf coerces the given expression into a boolean value. If the expression evaluates into a falsy value (values that are translated into false) then the content wont be rendered.

The following are all the values that javascript currently translates to false:

if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
if (``)

Upvotes: 7

seawave_23
seawave_23

Reputation: 1248

You're using an ngIf, means you are doing a conditional display of your value. When the value is 0, your condition evaluates to false and thus won't be displayed.

Upvotes: 3

Related Questions