DEV Community

Rens Jaspers
Rens Jaspers

Posted on • Edited on

Simplify Asynchronous Data Loading in Angular with ngx-data-loader

Asynchronous data loading is a common task in Angular applications, and it often involves handling multiple complexities such as managing loading states, error handling, and switching between templates in different loading phases. Dealing with these tasks can lead to repetitive boilerplate code, making it time-consuming and prone to errors.

As an Angular developer who has faced these challenges in various projects, I decided to create ngx-data-loader, an open-source package aimed at simplifying common data loading tasks in Angular applications. I'd like to highlight some of the features of the NgxDataLoaderComponent that could make your life easier.

Features

1. Automatically Track Loading State and Remove the Need for Related *ngIf Statements

The straightforward way to load data asynchronously in Angular involves subscribing to an Observable, storing the loading state (e.g. loading, loaded, error, data) in a component variable, and using multiple *ngIf statements to determine when to display the data, show an error message, or indicate that the data is still loading.

Because of the relatively low complexity of having a few loading state variables and *ngIf statements in your templates, developers often don't take the time to implement more efficient and reusable solutions for managing asynchronous data loading, leading to repetitive code and potential inconsistencies across the application.

This is where ngx-data-loader comes in handy. Using NgxDataLoaderComponent is as simple as providing a loadFn and a template for your data.

Let's look at an example in which we load an array of todos via HTTP with ngx-data-loader.

<!-- app.component.html -->
<ngx-data-loader [loadFn]="getTodos">
  <ng-template #loading> Loading todos... </ng-template>
  <ng-template #error> Failed to load todos. </ng-template>
  <ng-template #loaded let-todos>
    <div *ngFor="let todo of todos">
      Title: {{ todo.title }} <br />
      Completed: {{ todo.completed ? 'Yes' : 'No' }}
    </div>
  </ng-template>
</ngx-data-loader>
Enter fullscreen mode Exit fullscreen mode
/* app.component.ts */
@Component({
  ...
})
export class AppComponent {
  getTodos = () => this.http.get('https://jsonplaceholder.typicode.com/todos');

  constructor(private http: HttpClient) {}
}
Enter fullscreen mode Exit fullscreen mode

As you can see, there's no need for any loading state variables or *ngIf statements to display the appropriate template at the correct time in AppComponent; the NgxDataLoaderComponent manages the state and automatically switches between the #loading, #error, and #loaded templates.

2. Simplify Data Reloading

Setting up data reloading can often be a tedious task. With NgxDataLoaderComponent, it's easy! Just call its reload method.

You can do this in the template:

<!-- app.component.html -->
<button (click)="loader.reload()">reload todos</button>
<ngx-data-loader [loadFn]="getTodos" #loader> ... </ngx-data-loader>
Enter fullscreen mode Exit fullscreen mode

Or in TypeScript:

/* app.component.ts */
@Component({
  ...
})
export class AppComponent {
  @ViewChild("loader") loader: NgxDataLoaderComponent;
  ...
  reload() {
    this.loader.reload();
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Reactive Parameter-Based Loading

Content can be loaded based on external variables, such as the id in your route, or a value from an input field, through the [loadFnArgs] input. Any time the value of the input changes, loadFn is called with the new arguments.

In the example below, ngx-data-loader fetches search results based on keywords typed in an input field:

<!-- app.component.html -->
<input ngModel #searchbox />
<ngx-data-loader
  [loadFn]="searchProducts"
  [loadFnArgs]="searchbox.value"
  [debounceTime]="300"
>
  ...
</ngx-data-loader>
Enter fullscreen mode Exit fullscreen mode
/* app.component.ts */
@Component({
  ...
})
export class AppComponent {
  getTodos = () => this.http.get('https://jsonplaceholder.typicode.com/todos');

  constructor(private http: HttpClient) {}
}
Enter fullscreen mode Exit fullscreen mode

And in this example, we load a todo based on the id route parameter:

<!-- app.component.html -->
<ngx-data-loader [loadFn]="getTodo" [loadFnArgs]="route.params | async">
  ...
</ngx-data-loader>
Enter fullscreen mode Exit fullscreen mode
/* app.component.ts */
@Component({
  ...
})
export class AppComponent {
  getTodo = ({id: string}) => this.http.get(`https://jsonplaceholder.typicode.com/todos/${id}`);

  constructor(private http: HttpClient, public route: ActivatedRoute) {}
}
Enter fullscreen mode Exit fullscreen mode

NgxDataLoaderComponent resets the loading state when the id route parameter changes, offering a better user experience.

More Features

ngx-data-loader also offers advanced features like configurable retry and timeout, automatic cancellation of ongoing HTTP requests, and the ability to show stale data while reloading. Additionally, it provides various output events to track loading progress, such as dataLoaded, loadAttemptStarted, loadAttemptFailed, and loadAttemptFinished. You can explore these and other features in the API documentation.

Conclusion

By incorporating ngx-data-loader into your Angular projects, you can streamline your data loading process, improve code readability, and focus on building the core functionality of your application. Give it a try and see how it can enhance your development experience!

Don't forget to visit the ngx-data-loader GitHub repository for the latest updates, to report issues, or to contribute to the project. Happy coding!

Top comments (0)