Angular NgRx Store is a client-side data management pattern used in large applications. The Ngrx/Store implements the Redux pattern using RxJS observables of Angular. The ngrx/store builds on the concepts made famous by Redux and supercharges it with the backing of RxJS.

Angular NgRx Store Example

In this blog post, you will learn what Redux pattern, where the pattern can prove to be useful is, and how the design can be used to build better Angular applications.

Angular Ngrx is a group of Angular libraries for reactive extensions. To understand the NgRX concept, you must make a quick dive into the core Redux concepts and Reactive Programming concepts.

Redux

Redux is a predictable state container for JavaScript applications. Redux following the Unidirectional flow. Redux has a Single Store.

Redux cannot have multiple stores.

The store is divided into various state objects. So all we need is to maintain the single store, or we can say the only source of truth.

Three Principles Of Redux

Single source of truth.

The state is read-only.

Changes are made with pure functions.

Actions

Actions are payloads of information that send data from your application to your store. Actions are the payload that contains needed information to alter your store. Action has two properties.

1) Type

2) Payload

We will take these properties as an argument of a reducer to change the current state.

Action Creators

Action creators are precisely the functions that create actions.

function addTodo(text) { return { type: ADD_TODO, payload: text } }

Reducers

Actions describe the fact that something happened but don’t specify how the application’s state changes in response. That is the job of reducers.

Reducers are the pure functions that know what to do with a given action and the previous state of your application. The reducers will take the previous state from your store and apply a pure function to it and transform it into a new state. Pure Functions are base on Functional Programming.

Handling Actions

(previousState, action) => newState

Dispatcher

Dispatchers are an entry point for your application to dispatch your action. In Ngrx, there is a dispatch method directly on the store.

Store

A store is an object that brings them together. It is important to note that you will only have a single store in an NgRX application. If you want to split your data into a separate handling logic file then, you will have to use reducer composition instead of many stores.

Reactive Programming

Reactive programming is the way applications handle events and data flow in your angular applications. In reactive programming, you design your components and other pieces of your software to react to those changes.

The javascript library for reactive programming is RxJS. By providing observables and a lot of operators to transform incoming data, this library will help you handle events in your application. It is a component or service that reacts to data modifies.

Let us take an example to understand the Angular NgRx Store Example.

Step 1: Configure the Angular Project.

Install AngularCLI globally in our PC by typing the following command.

npm install -g @angular/cli

Now, fire the following command to create a project.

ng new ngrxstore

Okay, now create one component called blockchain by typing the following command.

ng g c blockchain

Now, we need to create one form in this component. In the src >> index.html file, add the Bootstrap CSS file.

<link rel="stylesheet" href="assets/css/bootstrap.min.css">

Add the following HTML code into the blockchain.component.html file.

<div class="panel panel-primary"> <div class="panel-body"> <form> <div class="form-group"> <label class="col-md-4">Coin Name</label> <input type="text" class="form-control" name="coin_name"/> </div> <div class="form-group"> <label class="col-md-4">Coin Price</label> <input type="text" class="form-control" name="coin_price"/> </div> <div class="form-group"> <button type="submit" class="btn btn-primary">Add</button> </div> </form> </div> </div>

Now, update the app.component.html file to show this form.

<h3 align="center">Angular ngrx/store Tutorial</h3> <div class="container"> <app-blockchain></app-blockchain> </div>

Go to the CMD and hit the following command.

ng serve --open

It will host our Angular application at port no: 4200

Step 2: Create a model for our application.

We need to define our application’s schema. So create one file inside the blockchain folder called blockchain.model.ts file.

export interface Blockchain { name: string; price: number; }

Here, I have defined the schema of our application.

Step 3: Install the ngrx library.

In your package.json file, update the following packages.

"@ngrx/core": "^1.2.0", "@ngrx/effects": "^4.1.1", "@ngrx/store": "^4.1.1",

Now, go to the terminal and hit the following command.

npm install

Step 4: Create a reducer for our application.

Go to the app folder and create one folder called reducers. In that folder, make one file called blockchain.reducer.ts

// blockchain.reducer.ts import { Blockchain } from './../blockchain/blockchain.model'; import { Action } from '@ngrx/store'; export const ADD_COIN = 'ADD_COIN'; export function addCoinReducer(state: Blockchain[] = [], action) { switch (action.type) { case ADD_COIN: return [...state, action.payload]; default: return state; } }

Here, I have defined the action type and reducer function. As we have previously discussed, Reducer is a pure function.

So the pure function always returns a new state. It does not modify the old state of the application.

Step 5: Configure the ngrx store in our application.

Go to the app.module.ts file and include the StoreModule in our application.

// app.module.ts import { StoreModule } from '@ngrx/store'; import { addCoinReducer } from './reducers/blockchain.reducer'; imports: [ BrowserModule, StoreModule.forRoot({blockchain: addCoinReducer}) ],

So, here, I have passed the reducer to the store now, if we need to change our application state the dispatch the actions and change the state and update the store.

Step 6: Add click event to the form.

Attach a button click event listener to the form. So our whole blockchainn.component.html looks like this.

<div class="panel panel-primary"> <div class="panel-body"> <form> <div class="form-group"> <label class="col-md-4">Coin Name</label> <input type="text" class="form-control" #name/> </div> <div class="form-group"> <label class="col-md-4">Coin Price</label> <input type="text" class="form-control" #price /> </div> <div class="form-group"> <button (click) = "addCoin(name.value, price.value)" class="btn btn-primary">Add</button> </div> </form> </div> </div>

Also, write the addCoin() function into the blockchain.component.ts file.

// blockchain.component.ts import { Blockchain } from './blockchain.model'; import { AppState } from './../app.state'; import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ selector: 'app-blockchain', templateUrl: './blockchain.component.html', styleUrls: ['./blockchain.component.css'] }) export class BlockchainComponent implements OnInit { constructor(private store: Store<AppState>) { } addCoin(name, price) { this.store.dispatch({ type: 'ADD_COIN', payload: <Blockchain> { name: name, price: price } }); } ngOnInit() { } }

Here, we need to implement the Global AppState in our application. So, the next step will be to implement it.

Step 7: Define the AppState.

In the app folder, create one file called app.state.ts.

// app.state.ts import { Blockchain } from './blockchain/blockchain.model'; export interface AppState { readonly blockchain: Blockchain[]; }

Step 8: Add validation in the form.

Include the ReactiveFormsModule in the app.module.ts file.

// app.module.ts import { ReactiveFormsModule } from '@angular/forms'; imports: [ BrowserModule, StoreModule.forRoot({blockchain: addCoinReducer}), ReactiveFormsModule ],

Okay, now our blockchain.component.ts file looks like this.

// blockchain.component.ts import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { Blockchain } from './blockchain.model'; import { AppState } from './../app.state'; import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ selector: 'app-blockchain', templateUrl: './blockchain.component.html', styleUrls: ['./blockchain.component.css'] }) export class BlockchainComponent implements OnInit { angForm: FormGroup; constructor(private store: Store<AppState>, private fb: FormBuilder) { this.createForm(); } createForm() { this.angForm = this.fb.group({ name: ['', Validators.required ], price: ['', Validators.required ] }); } addCoin(name, price) { this.store.dispatch({ type: 'ADD_COIN', payload: <Blockchain> { name: name, price: price } }); } ngOnInit() { } }

Here, I have written the validation logic for both of the input types.

Finally, our view blockchain.component.html file looks like this.

<div class="panel panel-primary"> <div class="panel-heading"> {{ title }} </div> <div class="panel-body"> <form [formGroup]="angForm" novalidate> <div class="form-group"> <label class="col-md-4">Coin Name</label> <input type="text" class="form-control" formControlName="name" #name /> </div> <div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['name'].errors.required"> Name is required. </div> </div> <div class="form-group"> <label class="col-md-4">Coin Price</label> <input type="text" class="form-control" formControlName="price" #price/> </div> <div *ngIf="angForm.controls['price'].invalid && (angForm.controls['price'].dirty || angForm.controls['price'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['price'].errors.required"> Price is required. </div> </div> <div class="form-group"> <button (click)="addCoin(name.value, price.value)" [disabled]="angForm.pristine || angForm.invalid" class="btn btn-primary">Add</button> </div> </form> </div> </div>

Now, if everything is fine, then you can add the data to the store.

Now, to verify it, we need to display that data on the front end. So make one view component to display the data.

Step 9: Create a view component to display data.

Go the terminal and hit the following command.

ng g c display

Subscribe to the store and fetch the data. So write the following code into the display.component.ts file.

// display.component.ts import { Blockchain } from './../blockchain/blockchain.model'; import { Component, OnInit } from '@angular/core'; import { AppState } from './../app.state'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs/Observable'; @Component({ selector: 'app-display', templateUrl: './display.component.html', styleUrls: ['./display.component.css'] }) export class DisplayComponent implements OnInit { coins: Observable<Blockchain[]>; constructor(private store: Store<AppState>) { this.coins = this.store.select(state => state.blockchain); } ngOnInit() { } }

Now, write the HTML view for this component.

<table class="table table-hover" *ngIf="coins!= 0"> <thead> <tr> <td>Coin Name</td> <td>Coin Price</td> </tr> </thead> <tbody> <tr *ngFor="let coin of coins | async"> <td>{{ coin.name }}</td> <td>{{ coin.price }}</td> </tr> </tbody> <table class="table table-hover" *ngIf="coins!= 0"> <thead> <tr> <td>Coin Name</td> <td>Coin Price</td> </tr> </thead> <tbody> <tr *ngFor="let coin of coins | async"> <td>{{ coin.name }}</td> <td>{{ coin.price }}</td> </tr> </tbody>

Add this view in the app.component.html file.

<h3 align="center">Angular ngrx/store Tutorial</h3> <div class="container"> <app-blockchain></app-blockchain> <br/> <app-display></app-display> </div>

Now, add the Coin name and Coin price, you will see it will store in the ngrx/store and fetch that data from the store and display that information.

Finally, Our Angular 9 NgRx Store Example is over.

Github code is the older version, but it will work with Angular 9 for sure.

I have put this code in the Github.

Fork Me On Github