The One Mistake Every Angular Developer Makes: Overusing *ngIf
Tags: angular, ngxloadwith
Published: 2023-06-03 07:12:25



Almost every Angular developer knows this scenario. You've got your Observable all set up for data retrieval from your API via Angular's HttpClient. Now, you're ready to display this data in your template, but here comes the challenging part: what about the states during the data loading process? If the data's loading, you need a spinner; if there's an error, show an error message; and finally, when the data is loaded, you display the data. It seems like a simple enough requirement, but it's also one of the most repetitive parts of writing an Angular application. Today, we will look at a new way to handle this problem.

## The Traditional Approach

The usual approach we find in most Angular projects involves using the `*ngIf` directive. A typical scenario might look like this:

```html
<div *ngIf="data$ | async as data; else loading"> {{ data }} </div>
<ng-template #loading>loading…</ng-template>
```

And then, we would sprinkle in another `*ngIf` statement for errors. This approach isn't complicated, but it’s a lot of repetition and the possibility of errors creeping in is high. Besides, the multiple `*ngIf` statements can clutter your template and require extra testing effort.

## A More Declarative Approach

Instead of dealing with the hassle of multiple `*ngIf` statements, we can adopt a more declarative approach. Just specify what needs to be displayed when the data is loaded and optionally specify what to display when the data is loading and when an error occurs. 

## Leveraging ngx-observe

[ngx-observe](https://npmjs.com/ngx-observe) is a brilliant library that allows for a more declarative way of dealing with loading states in Angular. It provides a structural directive that wraps around the logic of managing subscriptions and choosing the correct templates based on the loading state. 

Here is how it works:

```html
<div *ngxObserve="data$ as data; loading: myLoadingTemplate; error: myErrorTemplate"> {{ data }} </div>

<ng-template #myLoadingTemplate>loading…</ng-template>
<ng-template #myErrorTemplate let-error>{{error.message}}</ng-template>
```

As you can see, the ngx-observe directive allows you to focus on what matters - the templates for the different loading states. 

Check out Nils Mehlhorn's excellent article [here](https://dev.to/angular/handling-observables-with-structural-directives-in-angular-112j) for a deeper dive into how ngx-observe works.

## Introducing ngx-load-with

Inspired by ngx-observe, I decided to create a library called [ngx-load-with](npmjs.com/ngx-load-with). It provides similar functionality but with some extra features that allow for more flexibility. These include easy reloading and loading based on other variables like route parameters or search box input. 

While ngx-load-with still allows you to leverage the full power of RxJS, its aim is to streamline your code and reduce the necessity of using complex RxJS operations for common use cases. 

To give it a try, please check out the documentation [here](https://github.com/rensjaspers/ngx-load-with).

## Conclusion

Repetition and boilerplate code can often lead to errors and decrease the maintainability of your codebase. By adopting a more declarative approach to handle loading states in Angular, we can write cleaner, more reliable code. Both ngx-observe and ngx-load-with offer a more elegant way to handle loading states, allowing you to focus on the essence of your application - delivering an excellent user experience.