AppDividend
Latest Code Tutorials

Angular NgRx Store Tutorial Example From Scratch

Angular 5 ngrx/store Tutorial

20,597

Get real time updates directly on you device, subscribe now.

Angular NgRx Store Tutorial Example From Scratch is today’s topic. Ngrx/Store implements the Redux pattern using RxJS observables of Angular 2,4,5. ngrx/store builds on the concepts made famous by Redux and supercharges it with the backing of RxJS. In this blog post, you will learn what the Redux pattern is, where the pattern can prove to be useful, and how the design can be used to build better Angular applications. Ngrx is a group of Angular libraries for reactive extensions.

Angular NgRx Store Tutorial

To understand the NgRX concept, you must make a quick dive into the core Redux concepts and Reactive Programming concepts.

Redux

Redux is the predictable state container for JavaScript applications. Redux following the Unidirectional flow. Redux has a Single Store. Redux cannot have multiple stores. A  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 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 a NgRX application. If you want to split your data into 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 Tutorial.

Step 1: Configure the Angular Project.

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

Related Posts
1 of 13
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

ngrx store tutorial

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 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 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 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, 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 view component to display data.

Go the terminal and hit the following command.

ng g c display

Subscribe 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.

 

Angular 5 ngrx store tutorial with example from scratch

Finally, Our Angular NgRx Store Tutorial Example From Scratch is over.

icon
iconAngular 5 (formerly Angular 2) – The Complete Guide

I have put this code in the Github

Fork Me On Github

7 Comments
  1. AK says

    Nice Explanation! Thank You.

  2. valera says

    great work!

  3. ahmed says

    thanks good explaination

  4. Alejandro says

    Please help me to delete 1 item on store.

    I try this:

    case REMOVE_FROM_CART: {
    const index = state.findIndex((res) => res.id == action.payload.id);
    return [
    …state.slice(0, index),
    …state.slice(index + 1)
    ];
    }

    removeFromCart(payload) {
    this.store.dispatch({
    type: ‘REMOVE_FROM_CART’,
    payload: payload
    })
    }

    but this only change the position of my item

    1. sureshh says

      Hi, i have added removeCoin support. Unfortunately i could not upload code to this page and so code is uploaded at: https://gist.github.com/sureshhatgithub/f0d8fc4874d97467cfbcffae5dac6885

      Hope this helps.

  5. Shobhit Singh says

    Nice explanation,
    This tutorial cleared all my doubts related to ngrx

    Thanks

  6. PCD Pharma says

    Awesome explanation. Very helpful.

    Thank you.

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.