State Management Using NgRX In Angular

Introduction

 
In this post we will learn about State Management using NgRX in Angular.
 

About NgRx

 
NgRx Store provides reactive state management for Angular apps inspired by Redux. Unify the events in your application and derive state using RxJS.
 

Elements of NgRx

 
NgRx has the below components/elements. Understanding the below components help to implement the state management. 
  • Actions - Actions are events thats triggered from components.
  • Reducers - Reducers handles the state management.
  • Selectors - Selects are functions used to select, derive and compose the states.
  • Effects - Actions can interact with effects and get the data from server(mostly using services).

Actions

 
We need to create "store" and all the NgRX component folders, like Actions, Reducers, Selectors, Effects. Create a "employee.actions.ts" file and the below "GetEmployees" action. (Full code will be available at the end). 
  1. export class GetEmployees implements Action {  
  2.   readonly type = GET_EMPLOYEES;  
  3. }  

Reducers

 
Create a reducer with "EmployeeState" and the switch case to handler "GetEmployees" action result. 
  1. export interface EmployeeState {  
  2.   employees: Employee[];  
  3.   employee: Employee;  
  4.   loading: boolean;  
  5.   error: boolean;  
  6. }   
  1. case EmployeeActions.GET_EMPLOYEES: {  
  2.       return { ...state, loading: true };  
  3.     }  

Selectors

 
Next we will create "employees.selectors.ts" file and the below code will render object's state to component. 
  1. @Injectable()  
  2. export class EmployeeSelectors {  
  3.   
  4.   constructor(private store: Store<EntityState>) {}  
  5.   
  6.   employees$ = this.store.pipe(select(getAllEmployees));  
  7.   employee$ = this.store.pipe(select(getEmployee));  
  8.   employeeState$ = this.store.pipe(select(getEmployeeState));  
  9.   loading$ = this.store.pipe(select(getEmployeesLoading));  
  10.   
  11. }  

Effects

 
We need to add the below "Effect" method to get the employee data from "employeeDataService" and do the mapping after success or failure.
  1. @Effect()  
  2.    getEmployee$: Observable<Action> = this.actions$  
  3.      .pipe(  
  4.        ofType(EmployeeActions.GET_EMPLOYEE),  
  5.        switchMap((action: GetEmployeeAction) =>  
  6.          toAction(  
  7.            this.employeeDataService.getEmployee(action.payload),  
  8.            EmployeeActions.GetEmployeeSuccess,  
  9.            EmployeeActions.GetEmployeeError  
  10.          )  
  11.        )  
  12.      );  

Component code changes

 
In the "employee" component we have injected the "Store", "EmployeeSelectors" object. 
  1. constructor(  
  2.      private store: Store<EntityState>,  
  3.      private employeeSelectors: EmployeeSelectors) {  
  4.      this.employees$ = this.employeeSelectors.employees$;  
  5.      this.loading$ = this.employeeSelectors.loading$;  
  6.  }  
In "getEmployees" method, we need to dispatch the "GetEmployees" event which we created in "EmployeeAction".
  1. getEmployees() {  
  2.    console.log('Inside test');  
  3.      this.store.dispatch(new GetEmployees());  
  4.  }  
Let's run the application and see the results,
 
Employee data are loaded on the page load,
 
I clicked the edit link and Edit page got loaded.
 
After submitting the page, updated data is reflected in employee list page.
 

Summary

 
In this post we learned about state management using Angular -NgRX. The source code will be available in this GitHub Repository.