An Introduction to *ngxLoadWith: Simplifying Observable Data Loading in Angular
Tags: beginners, angular, ngxloadwith
Published: 2023-05-31 20:34:07

Hey there! If you've been working with Angular, you've likely had to handle Observable data loading. It can sometimes get a bit tricky, especially when you're dealing with things like manual state tracking or needing to subscribe and unsubscribe to observables manually. You may have also found your templates getting a bit cluttered with the same `*ngIf` statements over and over again.  Sound familiar? 

Well, that's why I built [ngx-load-with](https://npmjs.com/ngx-load-with). It's an Angular library that's designed to help simplify these tasks and keep your code cleaner. Here's a quick look at how you might use it:

```html
<!-- say hello to ngx-load-with structural directive! -->
<ul *ngxLoadWith="getTodos as todos; loadingTemplate: loading; errorTemplate: error">
  <li *ngFor="let todo of todos"> {{ todo.title }}</li>
</ul>

<ng-template #loading>Loading...</ng-template>
<ng-template #error let-error>{{error.message}}</ng-template>
```

```typescript
@Component({...})
export class MyComponent {
  getTodos = () => this.http.get<Todo[]>('api/todos');

  private http = inject(HttpClient);
}
```

## Key Features

Now that you've been introduced, let's walk through what *ngxLoadWith* can do for you:

- **Automated Loading State Tracking:** With *ngxLoadWith*, you can stop manually tracking the state of your loading operations. It'll take care of this behind the scenes.

- **Hands-off Subscription and Unsubscription:** Don't worry about the risk of memory leaks from forgetting to unsubscribe to observables. *ngxLoadWith* manages this for you, ensuring everything is cleaned up properly when a component is destroyed.

- **Clear and Simple Syntax:** The library uses a clean, straightforward syntax to help you keep your templates neat and tidy.

- **Template Phase Management:** *ngxLoadWith* makes it easy to specify which template should be shown in which phase, letting you step away from the confusing `*ngIf error / *ngIf data else loading` dance.

- **Handling Falsy Values:** If you've ever run into issues with the `*ngIf="data$ | async as data; else loading"` pattern when data emits a falsy value like false or 0, you'll appreciate how *ngxLoadWith* handles this scenario.

- **Easy Data Reloads:** Need to refresh your data? No problem, *ngxLoadWith* makes this simple.

- **Dynamic Data Loading:** You can pass any dynamic value as an 'args' input to the *ngxLoadWith* directive, triggering a reload of the data with that value as a new argument to your load function. This is great for scenarios where you need to load data based on changing values, such as route params or user input.

For a quick grasp of `ngx-load-with`'s capabilities, check out these live examples:

- [Basic Usage Example](https://stackblitz.com/edit/stackblitz-starters-ygxc6t?file=src%2Fmain.ts): Demonstrates the fundamental features of `ngx-load-with`, including loading and error templates.
- [Advanced Usage Example](https://stackblitz.com/edit/angular-kkldgb-kldaa7?file=src%2Fapp%2Fapp.component.html): Showcases an e-commerce search operation using `ngx-load-with`, featuring debounce time and a persistent display of previous search results for a nicer user experience.

For a deeper dive, keep on reading!

## Getting Started

### Installation

To install `NgxLoadWithDirective`, simply run the following command:

```bash
npm install ngx-load-with
```

Next, import the `NgxLoadWithModule` module in your Angular module:

```typescript
import { NgxLoadWithModule } from "ngx-load-with";

@NgModule({
  imports: [NgxLoadWithModule],
  ...
})
export class MyModule {}
```

### Basic Usage

With NgxLoadWithDirective, you can load data from an Observable and display it in your template with ease:

```html
<ul *ngxLoadWith="getTodos as todos">
  <li *ngFor="let todo of todos">{{todo.title}}</li>
</ul>
```

```typescript
@Component({...})
export class MyComponent {
  getTodos = () => this.http.get<Todo[]>('api/todos');

  private http = inject(HttpClient);
}
```

### Working with Loading and Error Templates

NgxLoadWithDirective allows you to display a loading message while data is being loaded and an error message if an error occurs:

```html
<ul
  *ngxLoadWith="getTodos as todos; loadingTemplate: loading; errorTemplate: error"
>
  <li *ngFor="let todo of todos">{{todo.title}}</li>
</ul>
<ng-template #loading>Loading...</ng-template>
<ng-template #error let-error>{{error.message}}</ng-template>
```

### Fetching Data Using Route Parameters

You can load data based on a parameter from the route:

```html
<div *ngxLoadWith="getTodo as todo; args: routeParams$ | async">
  {{todo.title}}
</div>
```

```typescript
@Component({...})
export class MyComponent {
  routeParams$ = inject(ActivatedRoute).params;

  getTodo = ({id}) => this.http.get<Todo>('api/todos/' + id);

  private http = inject(HttpClient);
}
```

Each time the route params change, it triggers `getTodo` with the latest params. 

### Searching Data

Fetch data based on user input:

```html
<input ngModel #searchbox />
<ul
  *ngxLoadWith="findTodos as results; args: searchbox.value; debounceTime: 300"
>
  <li *ngFor="let todo of todos">{{todo.title}}</li>
</ul>
```

Each searchbox value change triggers the search function. The `debounceTime` of 300 ms makes sure the server doesn’t get overwhelmed.  

```typescript
@Component({...})
export class MyComponent {
  findTodos = (keywords: string) => this.http.get<Todo[]>('api/todos', { params: { q: keywords} });

  private http = inject(HttpClient);
}
```

### Reloading Data

Reload data when a button is clicked:

```html
<button (click)="todosLoader.load()">Reload</button>

<ng-template #todosLoader="ngxLoadWith" [ngxLoadWith]="getTodos" let-todos>
  <div *ngFor="let todo of todos">{{todo.title}}</div>
</ng-template>
```

### And More...

For more information, check out the [documentation](https://github.com/rensjaspers/ngx-load-with).

## Conclusion

`NgxLoadWithDirective` offers a user-friendly way to handle Observable data loading in Angular applications. It abstracts away much of the complexities of RxJS, handles Observable unsubscriptions, and promotes consistent, reusable code. Whether you're an experienced Angular developer or new to the framework, `NgxLoadWithDirective` is a tool that can enhance your development process.

With less time spent managing Observable data loading, you can focus on creating an exceptional application. Consider trying [ngx-load-with](https://npmjs.com/ngx-load-with) in your next Angular project.

If you find this project useful, I would appreciate it if you could give it a star on [GitHub](https://github.com/rensjaspers/ngx-load-with).

Happy coding!

P.S. 
A special shoutout to [ngx-observe](https://github.com/nilsmehlhorn/ngx-observe), which served as a significant source of inspiration in the development of ngx-load-with.