DEV Community

Rens Jaspers
Rens Jaspers

Posted on • Updated on

An Introduction to *ngxLoadWith: Simplifying Observable Data Loading in Angular

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. 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:

<!-- 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>
Enter fullscreen mode Exit fullscreen mode
@Component({...})
export class MyComponent {
  getTodos = () => this.http.get<Todo[]>('api/todos');

  private http = inject(HttpClient);
}
Enter fullscreen mode Exit fullscreen mode

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: Demonstrates the fundamental features of ngx-load-with, including loading and error templates.
  • Advanced Usage Example: 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:

npm install ngx-load-with
Enter fullscreen mode Exit fullscreen mode

Next, import the NgxLoadWithModule module in your Angular module:

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

@NgModule({
  imports: [NgxLoadWithModule],
  ...
})
export class MyModule {}
Enter fullscreen mode Exit fullscreen mode

Basic Usage

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

<ul *ngxLoadWith="getTodos as todos">
  <li *ngFor="let todo of todos">{{todo.title}}</li>
</ul>
Enter fullscreen mode Exit fullscreen mode
@Component({...})
export class MyComponent {
  getTodos = () => this.http.get<Todo[]>('api/todos');

  private http = inject(HttpClient);
}
Enter fullscreen mode Exit fullscreen mode

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:

<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>
Enter fullscreen mode Exit fullscreen mode

Fetching Data Using Route Parameters

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

<div *ngxLoadWith="getTodo as todo; args: routeParams$ | async">
  {{todo.title}}
</div>
Enter fullscreen mode Exit fullscreen mode
@Component({...})
export class MyComponent {
  routeParams$ = inject(ActivatedRoute).params;

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

  private http = inject(HttpClient);
}
Enter fullscreen mode Exit fullscreen mode

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

Searching Data

Fetch data based on user input:

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

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

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

  private http = inject(HttpClient);
}
Enter fullscreen mode Exit fullscreen mode

Reloading Data

Reload data when a button is clicked:

<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>
Enter fullscreen mode Exit fullscreen mode

And More...

For more information, check out the documentation.

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 in your next Angular project.

If you find this project useful, I would appreciate it if you could give it a star on GitHub.

Happy coding!

P.S.
A special shoutout to ngx-observe, which served as a significant source of inspiration in the development of ngx-load-with.

Top comments (0)