Adding NGRX

Add the store, effects and store-devtools

NGRX Store contains the basic NGRX features like reducers, selectors, actions, and the store.

Reducers are pure functions meaning asynchronous actions cannot be implemented in them, to do that we need effects.

NGRX Effects allows for asynchronous actions by capitalizing on the RXJS library.

In order to be able to debug our application, we also have to add @ngrx/store-devtools

ng add @ngrx/store

ng add @ngrx/effects

ng add @ngrx/store-devtools

What has changed?

package.json will be updated to contain the three packages

 "packages": {
    "": {
      "name": "product-app",
      "version": "0.0.0",
      "dependencies": {
        "@angular/animations": "^14.0.0",
        "@angular/common": "^14.0.0",
        "@angular/compiler": "^14.0.0",
        "@angular/core": "^14.0.0",
        "@angular/forms": "^14.0.0",
        "@angular/platform-browser": "^14.0.0",
        "@angular/platform-browser-dynamic": "^14.0.0",
        "@angular/router": "^14.0.0",
        "@ngrx/effects": "^14.0.2",
        "@ngrx/store": "^14.0.2",
        "@ngrx/store-devtools": "^14.0.2",
        "json-server": "^0.17.0",
        "rxjs": "~7.5.0",
        "tslib": "^2.3.0",
        "zone.js": "~0.11.4"
      },
...
}

 

In app.module.ts
We now have StoreModule in the ngModule import and its import statement from @ngrx/store,
and StoreDevtoolsModule is also imported and added to the imports array.

We also have EffectsModule too.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { ProductsListComponent } from './products-list/products-list.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { ReactiveFormsModule } from '@angular/forms';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [AppComponent, ProductsListComponent, ProductDetailComponent],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    StoreModule.forRoot({}, {}),
    EffectsModule.forRoot([]),
    ReactiveFormsModule,
    StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: environment.production }),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

If you check the NGRX documentation you'd see them using the StoreModule.forRoot method, but we will be using a different approach which I will explain.

A store is a big object and it can get messy if not properly organized. One way of organizing is to use slices. So we use StoreModule.forFeature to set a Feature Slice, also it is a cleaner approach.

@NgModule({...
imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule,
    StoreModule.forRoot({}, {}),
    StoreModule.forFeature('app', appReducer), //We will create and import appReducer later
    EffectsModule.forRoot([AppEffects]), // We will create and import AppEffects later
    ReactiveFormsModule,
    StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: environment.production }),
  ],
...})
Discussion

6

0