Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 19, 2022 12:52 pm GMT

Building Reactive Angular Templates with NgRx Component

In this article, we'll look into the @ngrx/component library used to build reactive Angular templates in a performant way. It contains a set of declarables that are primarily used for rendering observable events and can work in both zone-full and zone-less mode.

Installation

To install the @ngrx/component package, run one of the following commands:

// Angular CLIng add @ngrx/component// NPMnpm i @ngrx/component// Yarnyarn add @ngrx/component

Push Pipe

The ngrxPush pipe is used for displaying observable values in the template. To use it, import the PushModule to an Angular module or standalone component:

import { PushModule } from '@ngrx/component';@Component({  // ... other metadata  standalone: true,  imports: [    // ... other imports    PushModule,  ],})export class ProductDetailsComponent {  readonly product$ = this.store.select(selectActiveProduct);  constructor(private readonly store: Store) {}}

PushModule is available since version 14. If you're using an older version of the @ngrx/component package, import the ReactiveComponentModule.

The ngrxPush pipe is an alternative to the async pipe and can be used in the following way:

<ngrx-product-form  [product]="product$ | ngrxPush"></ngrx-product-form>

Similar to the async pipe, the ngrxPush pipe returns the last emitted value of the passed observable or undefined if there are no emitted values. However, there are two key differences compared to the async pipe:

  • The ngrxPush pipe will not trigger change detection when an observable emits the same values in a row.
  • The ngrxPush pipe will trigger change detection when an observable emits a new value in zone-less mode.

Since version 14, the @ngrx/component package uses the global rendering strategy in both zone-full and zone-less mode. In previous versions, it used the native local rendering strategy in zone-less mode, which caused performance issues.

Let Directive

The *ngrxLet directive is used for rendering observable events in the template. To use it, import the LetModule to an Angular module or standalone component:

import { LetModule } from '@ngrx/component';@Component({  // ... other metadata  standalone: true,  imports: [    // ... other imports    LetModule,  ],})export class ProductListComponent {  readonly products$ = this.productsService.getProducts({ limit: 10 });  readonly totalCount$ = this.productsService.getTotalCount();  constructor(private readonly productsService: ProductsService) {}}

LetModule is available since version 14. If you're using an older version of the @ngrx/component package, import the ReactiveComponentModule.

The *ngrxLet directive can be used in the following way:

<ng-container *ngrxLet="totalCount$ as totalCount">  <h2>Products ({{ totalCount }})</h2>  <p *ngIf="!totalCount" class="info-alert">    There are no products.  </p></ng-container>

At first, it seems that we can achieve the same result using the *ngIf directive and async pipe:

<ng-container *ngIf="totalCount$ | async as totalCount">  <h2>Products ({{ totalCount }})</h2>  <p *ngIf="!totalCount" class="info-alert">    There are no products.  </p></ng-container>

However, the *ngIf directive will only create an embedded view if the totalCount is not zero (truthy value), but not if it is zero (falsy value). On the other hand, the *ngrxLet directive will create an embedded view when an observable emits a value, regardless of whether it is truthy or falsy.

Tracking Different Observable Events

The *ngrxLet directive provides the ability to display different content based on the current observable state. For example, we can display an error alert if an observable emits the error event:

<ng-container *ngrxLet="products$ as products; $error as error">  <ngrx-product-card    *ngFor="let product of products"    [product]="product"  ></ngrx-product-card>  <p *ngIf="error" class="error-alert">{{ error.message }}</p></ng-container>

Displaying thrown error is possible since version 14. In previous versions, the value of $error is true when the passed observable emits the error event.

In addition to error, we can also track the complete event:

<ng-container  *ngrxLet="saveProgress$ as progress; $complete as complete">  <mat-progress-spinner    [value]="progress"    mode="determinate"  ></mat-progress-spinner>  <p *ngIf="complete" class="success-alert">    Product is successfully saved!  </p></ng-container>

Using Suspense Template

Also, there is an option to pass the suspense template to the *ngrxLet directive:

<ng-container *ngrxLet="products$ as products; suspenseTpl: loading">  <ngrx-product-card    *ngFor="let product of products"    [product]="product"  ></ngrx-product-card></ng-container><ng-template #loading>  <mat-spinner></mat-spinner></ng-template>

The suspense template will be rendered when the passed observable is in a suspense state. In the example above, the loading spinner will be displayed until the products$ observable emits a list of products. When this happens, the loading spinner will be removed from the DOM and products will be displayed.

Using suspense template with the *ngrxLet directive is available since version 14.

Using Aliases for Non-Observable Values

In addition to observables and promises, the *ngrxLet directive can also accept static (non-observable) values as an input argument. This feature provides the ability to create readable templates by using aliases for deeply nested properties:

<ng-container *ngrxLet="productForm.controls.price as price">  <input type="number" [formControl]="price" />  <ng-container *ngIf="price.errors && (price.touched || price.dirty)">    <p *ngIf="price.errors.required">Price is a required field.</p>    <p *ngIf="price.errors.min">Price cannot be a negative number.</p>  </ng-container></ng-container>

Passing non-observable values to the *ngrxLet directive is available since version 14.

Summary

Many new and powerful features have been added in version 14:

  • Separate modules for LetDirective and PushPipe
  • Displaying emitted error in the template
  • Using aliases for non-observable values
  • Handling suspense state in the template
  • Strong typing for LetDirective and PushPipe

Also, this library has been almost completely rewritten for better performance. If you haven't used it before, give it a try and let us know your impressions!

By the way, the @ngrx/component package recently reached 30k downloads per week on NPM!

ngrx-component-npm

Resources

Peer Reviewers

Big thanks to Brandon Roberts and Tim Deschryver for giving me helpful suggestions on this article!


Original Link: https://dev.to/ngrx/building-reactive-angular-templates-with-ngrx-component-4m1e

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To