npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ngx-load-with

v4.1.2

Published

Welcome to `NgxLoadWith`, a powerful tool for Observable-based data loading in Angular.

Downloads

627

Readme

NgxLoadWith

Welcome to NgxLoadWith, a powerful tool for Observable-based data loading in Angular.

Build status NPM version NPM downloads MIT license Minzipped size CodeFactor Codecov

<div *ngxLoadWith="unreadCount$ as count">
  You have {{ count }} unread messages
</div>
<!-- Output: You have 0 unread messages -->

With NgxLoadWithDirective, you can easily display data from an Observable in your template. You won’t have to worry about performance, errors, or managing the loading state. Plus, it lets you handle reloading and more advanced tasks, all with minimal RxJS knowledge.

Key Features:

  • 💡 Declarative UI State Management: Automates transitions between loading, success, and error states, eliminating the need for if-statements.
  • 🚀 Performance: Optimized for efficiency, aligns with Angular's OnPush change detection.
  • 🛡️ Memory Safety: Automatically unsubscribes from Observables to prevent memory leaks.
  • ⚖️ Lightweight and Independent: Zero dependencies, easily integrates into any project.
  • ⚡️ Dynamic Data Loading: Supports loading data based on dynamic parameters.
  • 🎮 Control Over Data Loading: Offers methods for reloading and canceling requests.

Table of Contents

Demo

Check out these live examples of NgxLoadWith in action:

Installation

To install NgxLoadWith, run the following command:

npm install ngx-load-with

Note: you need Angular version 16 or higher. For Angular 15, use ngx-load-with@1.

To use NgxLoadWith, import NgxLoadWithDirective in your Angular component:

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

@Component({
  selector: "app-my-component",
  templateUrl: "./my-component.component.html",
  standalone: true,
  imports: [NgxLoadWithDirective],
})
export class MyComponent {}

Note: in projects using NgModules, NgxLoadWithModule can be imported in your Angular module.

Usage

Basic usage

Load data from an Observable and display it in your template:

⚡️ Live Example

<ul *ngxLoadWith="todos$ as todos">
  @for (todo of todos; track todo.id) {
    <li>{{ todo.title }}</li>
  }
</ul>
@Component({...})
export class MyComponent {
  todos$ = inject(HttpClient).get<Todo[]>('api/todos');
}

Showing loading and error templates

Display a loading message while data is being loaded, and an error message if an error occurs:

⚡️ Live Example

<ul
  *ngxLoadWith="todos$ as todos; loadingTemplate: loading; errorTemplate: error"
>
  @for (todo of todos; track todo.id) {
    <li>{{ todo.title }}</li>
  }
</ul>
<ng-template #loading>Loading...</ng-template>
<ng-template #error let-error>{{ error.message }}</ng-template>

Loading based on changes to other data

NgxLoadWith can respond to dynamic data changes using a function in place of a plain Observable. This function is invoked when the input arguments change.

Example 1: Fetching data using route parameters:

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

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

  private http = inject(HttpClient);
}

Example 2: Searching data based on user input:

<input ngModel #searchbox />
<ul *ngxLoadWith="findTodos as todos; args: searchbox.value; debounceTime: 300">
  @for (todo of todos; track todo.id) {
    <li>{{ todo.title }}</li>
  }
</ul>
@Component({...})
export class MyComponent {
  findTodos = (keywords: string) => this.http.get<Todo[]>('api/todos', { params: { q: keywords} });

  private http = inject(HttpClient);
}

In these examples, getTodo and findTodos are functions that return Observables based on dynamic parameters. When these parameters change, NgxLoadWith automatically invokes the respective function with the updated parameters, effectively reloading the data.

Reloading

Reload data when a button is clicked:

⚡️ Live Example

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

<ng-template #todosLoader="ngxLoadWith" [ngxLoadWith]="todos$" let-todos>
  <ul>
    @for (todo of todos; track todo.id) {
      <li>{{ todo.title }}</li>
    }
  </ul>
</ng-template>

Important: If you plan to use the NgxLoadWithDirective.load method in your template, please note that you cannot use the *ngxLoadWith microsyntax. See note on microsyntax for more details.

Showing previously loaded data while reloading

Reload data when a button is clicked, but display stale data while the new data is being loaded:

⚡️ Live Example

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

<ng-template
  #todosLoader="ngxLoadWith"
  [ngxLoadWith]="todos$"
  [ngxLoadWithStaleData]="true"
  let-todos
  let-loading="loading"
>
  @if (loading) {
    Reloading...
  }
  <ul>
    @for (todo of todos; track todo.id) {
      <li>{{ todo.title }}</li>
    }
  </ul>
</ng-template>

Important: If you plan to use the NgxLoadWithDirective.load method in your template, please note that you cannot use the *ngxLoadWith microsyntax. See note on microsyntax for more details.

Note on Microsyntax

When using the NgxLoadWithDirective, you have two options for syntax:

  1. Microsyntax: This shorter, more compact syntax is easy to read and sufficient for many common use cases. For example:

    <div *ngxLoadWith="getTodo as todo; args: id">...</div>
  2. Normal syntax: The longer form syntax is necessary when you need to create a directive reference in your template or listen to output events emitted by the directive. For example:

    <ng-template
      #loader="ngxLoadWith"
      [ngxLoadWith]="getTodo"
      [ngxLoadWithArgs]="id"
      let-todo
    >
      <div>...</div>
    </ng-template>

    In this example, #loader="ngxLoadWith" creates a reference to the NgxLoadWithDirective instance, allowing you to call the load() method in your template:

    <button (click)="loader.load()">Reload</button>

    Additionally, using the normal syntax allows you to listen to output events:

    <ng-template
      #loader="ngxLoadWith"
      [ngxLoadWith]="getTodos"
      (loadSuccess)="onSuccess($event)"
      (loadError)="onError($event)"
      let-todos
    >
      <div>...</div>
    </ng-template>

API

Inputs

  • ngxLoadWith: (args?: any) => Observable<T> | Observable<T>: A function returning an Observable of the data to be loaded, or a plain Observable.
  • args: unknown: An argument to be passed to the ngxLoadWith function (if it's a function). Changes to this argument will trigger a reload.
  • loadingTemplate: TemplateRef<unknown>: An optional template to be displayed while the data is being loaded.
  • errorTemplate: TemplateRef<ErrorTemplateContext>: An optional template to be displayed when an error occurs while loading the data.
  • debounceTime: number: The amount of time in milliseconds to debounce the load trigger.
  • staleData: boolean: A boolean indicating whether to show previously loaded data while reloading.

Outputs

  • loadStart: EventEmitter<void>: Emits when the data loading process starts.
  • loadSuccess: EventEmitter<T>: Emits when the data loading process is successful.
  • loadError: EventEmitter<Error>: Emits when an error occurs while loading the data.
  • loadFinish: EventEmitter<void>: Emits when the data loading process finishes, regardless of success or failure.
  • loadingStateChange: EventEmitter<LoadingState<T>>: Emits when the loading state changes.

Important: If you plan to listen to the above output events, please note that you cannot use the *ngxLoadWith microsyntax. See note on microsyntax for more details on using the normal syntax.

Methods

  • load(): Triggers a reload of the data. Previous load requests are cancelled.
  • cancel(): Cancels any pending load requests.
  • setData(data: T): Updates the loading state as if the passed data were loaded through the ngxLoadWith function.
  • setError(error: Error): Updates the loading state as if the passed error were thrown by the ngxLoadWith function.

Important: If you plan to use the above methods in your template, please note that you cannot use the *ngxLoadWith microsyntax. See note on microsyntax for more details on using the normal syntax.

Interfaces

interface LoadingState<T = unknown> {
  loading: boolean;
  loaded: boolean;
  error?: Error | null;
  data?: T;
}

interface LoadedTemplateContext<T = unknown> {
  $implicit: T;
  ngxLoadWith: T;
  loading: boolean;
}

interface ErrorTemplateContext {
  $implicit: Error;
  retry: () => void;
}

License

NgxLoadWith is licensed under the MIT License. See the LICENSE file for details.

Contributing

Contributions are welcome! See the CONTRIBUTING file for details.

Credits

This project is developed and managed by Rens Jaspers. It draws significant inspiration from ngx-observe and react-async.