1.0.1 • Published 1 year ago

ngx-async-directive v1.0.1

Weekly downloads
-
License
-
Repository
github
Last release
1 year ago

ngx-async-directive 🪄 Angular 15+

Idea

Directive allows you to work with Observable and visually represent its statuses, like Loading, Error, Success.

Add the ngxAsync structural directive on your element.

You can use the ngxAsync directive with ng-template as well. In this case, data from your Observable will be in the context of the ng-template by the $implicit key. So, you can get this data by defining let-data on the ng-template.

StackBlitz example #1 (Data Loading)

StackBlitz example #2 (Delete "Action")

StackBlitz example #3 (Search "Action")

Installation

npm install ngx-async-directive --save

Get Started

Add NgxAsyncModule to your module.

import { NgxAsyncModule } from 'ngx-async-directive';

@NgModule({
    imports: [NgxAsyncModule]
})
export class AppModule {}

Usage by representing data and its statuses

In this example will be rendered loadingTemplate while there is no data from labels$ Observable.

If labels$ Observable has an error then it will be rendered errorTemplate.

if labels$ Observable will have the status "next" (loaded), then will be rendered the mat-list component.

example.component.html

<ng-container *ngxAsync="labels$ as labels; loading: loadingTemplate; error: errorTemplate;">
    <mat-list>
        <mat-list-item *ngFor="let label of labels">
            {{ label.name }}
        </mat-list-item>
    </mat-list>
</ng-container>

<ng-template #loadingTemplate>
    <div class="loading">
        Loading...
    </div>
</ng-template>

<ng-template #errorTemplate>
    <div class="error">
        Can't load data
    </div>
</ng-template>

example.component.ts

@Component({})
export class ExampleComponent {
    public readonly labels$ = this.labelsService.getAll();

    constructor(
        private readonly labelsService: LabelsService
    ) {}
}

Usage by representing "action" and its statuses

In this example will be rendered button element.

When button will be clicked, then onDeleteButtonClick handler will change field deletingProcess$ to Observable from the service.

After that loadingTemplate will be rendered while there is no data.

If the deletingProcess$ Observable has an error then it will be rendered errorTemplate.

If the deletingProcess$ Observable will be completed then it will be rendered successTemplate.

example.component.html

<mat-card>
    <ng-template
        [ngxAsync]="deletingProcess$"
        [ngxAsyncLoading]="loadingTemplate"
        [ngxAsyncError]="errorTemplate"
        [ngxAsyncSuccess]="successTemplate">
        <button
            mat-raised-button
            (click)="onDeleteButtonClick()">
            Delete
        </button>
    </ng-template>
</mat-card>

<ng-template #loadingTemplate>
    <div class="loading">
        Loading...
    </div>
</ng-template>

<ng-template #errorTemplate>
    <div class="error">
        Something went wrong :(
    </div>
</ng-template>

<ng-template #successTemplate>
    <div class="success">
        Card deleted!
    </div>
</ng-template>

example.component.ts

@Component({})
export class ExampleComponent {
    public deletingProcess$: Observable<unknown> | null = null;

    constructor(
        private readonly usersService: UsersService
    ) {}

    public onDeleteButtonClick(): void {
        this.deletingProcess$ = this.usersService.delete();
    }
}