@ngrx-utils/store
TypeScript icon, indicating that this package has built-in type declarations

0.14.0 • Public • Published

@ngrx-utils CircleCI Maintainability codecov Known Vulnerabilities

@ngrx-utils

Reusable logic library for Angular application

Quick start

npm i -S @ngrx-utils/store
# or
yarn add @ngrx-utils/store

What in the box?

routerLinkMatch directive

This directive will give you ability to add a class to the element when router url match a regular expression. The syntax is same with ngClass but replace the true/false expression with your string based regexp (like the string you pass to new RegExp('')).

Example: active-class will be added to a tag when router URL contains this segment: products/12345

<a routerLink="/products"
   [routerLinkMatch]="{
     "active-class": "products/\\d+"
   }"></a>

push pipe

This is a modified version of async pipe in @angular/common package. All the code implement are almost the same but this push pipe will call detectChanges() instead of markForCheck() so your pipe continue to work even in {ngZone: 'noop'} environment.

// main.ts
platformBrowserDynamic()
  .bootstrapModule(AppModule, { ngZone: 'noop' })
  .catch((err) => console.log(err));

// app.module.ts
import { PushPipeModule } from '@ngrx-utils/store';
@NgModule({
  imports: [PushPipeModule],
})
export class AppModule {}
// heavy-compute.component.ts
import { Component, OnInit, NgZone } from '@angular/core';
@Component({
  template: `<h2>Test: {{ test$ | push }}</h2>`,
})
export class HeavyComputeComponent implements OnInit {
  compute() {
    //...heavy computing
  }

  ngOnInit() {
    this.compute();
  }
}

ngLet directive

We often use *ngIf="stream$ | async as stream" to subscribe to an observable property and rename it to a template variable. But with nested template, *ngIf might remove your template which may not be expected.

NgLet to rescue:

import { NgLetModule } from '@ngrx-utils/store';

@NgModule({
  imports: [NgLetModule],
})
export class FeatureModule {}

Replace *ngIf with *ngLet:

<ng-container *ngLet="(filterDate$ | async) as filterDate">
  <pick-date
    [registeredAt]="(device$ | async)?.registeredAt"
    [firstDate]="filterDate?.from"
    [secondDate]="filterDate?.to"
  ></pick-date>
</ng-container>

*ngLet just hold a reference to the result of async pipe in a template variable and don't have any special logic like structure directives such as *ngIf or *ngFor so it run faster and very handy.

You can also subscribe to multiple observable separately with *ngLet like this:

<ng-container
  *ngLet="{
        device: device$ | async,
        date: filterDate$ | async
      } as options"
>
  <pick-date
    [registeredAt]="options.device?.registeredAt"
    [firstDate]="options.date?.from"
    [secondDate]="options.date?.to"
  ></pick-date>
</ng-container>

Actually this is an feature request in angular for quite long time as described in here but not yet been accepted.

untilDestroy pipeable operator

Have you ever feel odd when have to repeat calling unsubscribe with subscriptions in ngOnDestroy, or creating a Subject property, add takeUntil() to subscription, call next() in ngOnDestroy?

With untilDestroy pipeable operator:

import { untilDestroy } from '@ngrx-utils/store';

export class MyComponent implements OnDestroy {
  user: User;

  constructor(userService: UserService) {
    userService
      .getUsers()
      /** Automatically unsubscribe on destroy */
      .pipe(untilDestroy(this))
      .subscribe((user) => (this.user = user));
  }

  /** Must have */
  ngOnDestroy() {}
}

NOTE: You still have to declare ngOnDestroy in Component because Angular does not support dynamically add component method in AOT mode

Credit to @SanderElias, this operator is inspired from his idea but he's currently not publishing it as an npm package.

How to contribute

  • Fork this repo
  • Add your awesome feature and include it in the top level export
  • Send a PR here and describe some use cases.

Package Sidebar

Install

npm i @ngrx-utils/store

Weekly Downloads

189

Version

0.14.0

License

MIT

Unpacked Size

125 kB

Total Files

25

Last publish

Collaborators

  • sandangel