@ngrx-utils/store
v0.14.0
Published
Utils Library for Angular
Downloads
677
Readme
@ngrx-utils
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.