Handling Falsy Values Emitted from Observables in Angular
Tags: angular, rxjs, observables, falsyvalues
Published: 2021-04-21 20:00:32

Preston Lamb | ng-conf | Sep 2020

In the last year or so, I’ve been fully embracing reactive programming in my Angular apps. That means goodbye `subscribe` and hello `async` pipe! It’s been great, but there have been a couple times where the `async` pipe, in conjunction with the `*ngIf` structural directive, have not worked as I needed them to. The issue arises when the emitted value from the observable is falsy. When the emitted value is falsy, the `*ngIf` doesn’t output the content on the screen. I understand why that happens, but many times the falsy value is a valid result and should be displayed. In this post, we’ll cover an easy way to still use the `async` pipe and `*ngIf` while still outputting falsy values.

### **The Issue Explained**
Recently, I was working on an application at work where we needed to output the emitted value of an observable. The value was a number with zero being a valid result. We also wanted to display a loading spinner while waiting on data from the API. We did that with the `*ngIf` structural directive and the `else` option that goes along with it. Here’s a brief sample of what that looked like:

```
<div 
  *ngIf=”observableValue$ | async as value; else backupLoader”>
    {{ value }}
</div>
<ng-template #backupLoader>
  <app-loader></app-loader>
</ng-template>
```

This worked in most situations. Before the observable emitted the response from the API, the loader would show up on the screen. As soon as the value came back, it replaced the loader. The only time it didn’t work was when the emitted value was 0. The loader would stay on the screen and 0 would never show up. The reason for that is that 0 is a falsy value, and thus the `*ngIf` never stopped showing the loader.

One solution to get around this was to convert the returned value to a string and not a number. I didn’t want to have to alter the value though to get my desired result. [I turned to Twitter](https://twitter.com/prestonjlamb/status/1305538951936057356) for a little bit of help and came up with the following solution.

### **Wrapping Observable Values in Objects**
The easiest way to solve this issue is to turn the emitted value from the observable into an attribute on an object. You can do this in the component class file, or directly in the HTML. I’m going to do this directly in the HTML. Here’s what that looks like:

```
<ng-container 
  *ngIf=”{ observableValue: observableValue$ | async } as data”>
    <div>{{ data.observableValue }}</div>
</ng-container>
```

What we’ve done here is subscribed to the observable with the `async` pipe, and put the value into the `observableValue` attribute of an object. Notice the curly brackets inside the `*ngIf` structural directive. We then use the `as` syntax, which renames the variable for use in the template. Inside the double curly brackets, the result is output by accessing the `observableValue` attribute of the `data` object.

The `*ngIf` directive on the `ng-container` element will now always evaluate to `true` because we have created that object. So, no matter what value is emitted from the observable, we will output it to the screen.

### **What About the Loader?**
Wrapping the observable in an object was nice, and now we can output falsy values. But if we stop with the example in the previous section we’ll have lost our loader element. So the last part to figure out is how to combine wrapping the observable in an object with showing the loader element before the data is loaded. We can do that by using a second `*ngif` inside the `ng-container`, like this:

```
<ng-container 
  *ngIf=”{ observableValue: observableValue$ | async } as data”>
    <div *ngIf=”
      data.observableValue !== null && 
      data.observableValue !== undefined; 
      else backupLoader”
    >
      {{ data.observableValue }}
    </div>
    <ng-template #backupLoader>
      <app-loader></app-loader>
    </ng-template>
</ng-container>
```

The `ng-container` is the same here as it was before. But the `div` that wraps the `data.observableValue` output now has a new `*ngIf` placed on it. The two checks added here are that the `observableValue` attribute value is not `null` or `undefined`. If the value is null or undefined, then the loader is shown. Otherwise, the value is output (including if it’s falsy).

### **Conclusion**
I have been working with Angular for a long time at this point, and am really bummed that I hadn’t figured this out years ago. This is a great way to output falsy values while using the `async` pipe and the `*ngIf` structural directive. I will be using this a lot going forward, and hope that this will be useful for you as well.

I also want to give credit to [Maxime Robert](https://twitter.com/maxime1992) for writing [this great article](https://dev.to/maxime1992/angular-easily-extract-a-falsy-value-from-an-observable-using-the-async-pipe-112g) and to [Aaron Frost](https://twitter.com/aaronfrost) for [the suggestion on Twitter](https://twitter.com/aaronfrost/status/1305542975087288328?s=20).

## **ng-conf: The Musical is coming**
ng-conf: The Musical is a two-day conference from the ng-conf folks coming on April 22nd & 23rd, 2021. Check it out at [ng-conf.org](https://www.2021.ng-conf.org/)

###### Thanks to Steven Guitar.