Real Time Example of NGRX + Angular — Part 2

Nikhil Kapoor
Sep 2, 2018 · 5 min read

Continuing previous article (Real Time Example of NGRX + Angular), We’ll talk about our next topic “Setting up the store for Employee and Getting Data”

Let’s Make a check list

  • Create Employee Folder
  • Create Sub folders like Action , Effects, Selector, Model etc
  • Create files in sub folders like ”Employee.action.ts” for action and Employee.effect.ts for effects. same for others
  • Create a module for employee store
  • Make them working by writing the code

Setting up the store

Like in the previous article, we made a folder called store. In the same folder, we will create a new folder name “Employee” with sub folders as in image below

  • C̶r̶e̶a̶t̶e̶ ̶E̶m̶p̶l̶o̶y̶e̶e̶ ̶F̶o̶l̶d̶e̶r̶
  • Create Sub folders like Action , Effects, Selector, Model etc
  • Create files in sub folders like ”Employee.action.ts” for action and Employee.effect.ts for effects. same for others
  • Create a module for employee store
  • Make them working by writing the code
Architecture of NGRX Store

Architecture of an application is totally depends on the size and complexity of the project but since we are here dealing with the real-time application. so i believe, the above mentioned architecture is good one. We can easily add Human Resource folder in store, if required. New developer can easily recognize like “oh ! i found the store folder it must be NGRX and yeah Employee folder must be feature”.

Now in the same Employee folder we will create Action, Selector, Effect folder to easily distinguish in between them.

  • C̶r̶e̶a̶t̶e̶ ̶E̶m̶p̶l̶o̶y̶e̶e̶ ̶F̶o̶l̶d̶e̶r̶
  • C̶r̶e̶a̶t̶e̶ ̶S̶u̶b̶ ̶f̶o̶l̶d̶e̶r̶s̶ ̶l̶i̶k̶e̶ ̶A̶c̶t̶i̶o̶n̶ ̶,̶ ̶E̶f̶f̶e̶c̶t̶s̶,̶ ̶S̶e̶l̶e̶c̶t̶o̶r̶,̶ ̶M̶o̶d̶e̶l̶ ̶e̶t̶c̶
  • Create files in sub folders like ”Employee.action.ts” for action and Employee.effect.ts for effects. same for others
  • Create a module for employee store
  • Make them working by writing the code

Later , we can create a module of this Employee and store and can inject into main app module to follow the sub module architecture.

In the sub-folder create the files with “feature-name.[action/effect/selector/model].ts” for example employee.actions.ts

and we are done with 3 steps here

  • C̶r̶e̶a̶t̶e̶ ̶E̶m̶p̶l̶o̶y̶e̶e̶ ̶F̶o̶l̶d̶e̶r̶
  • C̶r̶e̶a̶t̶e̶ ̶S̶u̶b̶ ̶f̶o̶l̶d̶e̶r̶s̶ ̶l̶i̶k̶e̶ ̶A̶c̶t̶i̶o̶n̶ ̶,̶ ̶E̶f̶f̶e̶c̶t̶s̶,̶ ̶S̶e̶l̶e̶c̶t̶o̶r̶,̶ ̶M̶o̶d̶e̶l̶ ̶e̶t̶c̶
  • C̵r̵e̵a̵t̵e̵ ̵f̵i̵l̵e̵s̵ ̵i̵n̵ ̵s̵u̵b̵ ̵f̵o̵l̵d̵e̵r̵s̵ ̵l̵i̵k̵e̵ ̵”̵E̵m̵p̵l̵o̵y̵e̵e̵.̵a̵c̵t̵i̵o̵n̵.̵t̵s̵”̵ ̵f̵o̵r̵ ̵a̵c̵t̵i̵o̵n̵ ̵a̵n̵d̵ ̵E̵m̵p̵l̵o̵y̵e̵e̵.̵e̵f̵f̵e̵c̵t̵.̵t̵s̵ ̵f̵o̵r̵ ̵e̵f̵f̵e̵c̵t̵s̵.̵ ̵s̵a̵m̵e̵ ̵f̵o̵r̵ ̵o̵t̵h̵e̵r̵s̵
  • Create a module for employee store
  • Make them working by writing the code

Now create a module and name it Employee.store-module.ts, completing out 4th step also.

Let’s start with the working of NGRX, keeping the goal, to show the list of employee on home page.

Create an effect

In above example , I added some mock data of type IEmployee[] and a function loadEmployeeEffect. let’s deep dive into it first.

@Effect() loadEmployeeEffect$ = combineLatest(this.store.pipe(select(getEmployeeLoaded)),).pipe(filter(([loaded]) => !loaded),switchMap(() => {return of(new InformationFetchSucceeded(EMPLOYEE_INFO));}),);

First line, “combine latest” is doing nothing, but giving a collection of result to my filter function. You can read more about this on Rxjs.

If you’ll notice the second line ,“this.store.pipe(select(getEmployeeLoaded))”, you’ll see a new funtion “getEmployeeLoaded” it is a selector function to which we are subscribing for the result. We will talk about this selector later.

Now getEmployeeLoaded, in short, telling my function to call the API. If the loaded variable is false means that API is not loaded yet. Hence on the page load whenever selector get initialize. The effect will automatically send an API hit since it is subscribing to the selector.

Now update the model.ts, action.ts and reducer.ts as mentioned below

export interface IEmployee { //model.tsid: string,name: string,department: string,salary: string,isMarried: boolean,}

Action.ts

import { Action } from '@ngrx/store';import { IEmployee } from '../Models/employee.model';export enum ActionTypes {
LOAD_EMPLOYEE_INFORMATION = 'EMPLOYEE_INFORMATION/LOAD',
INFORMATION_FETCH_SUCCEEDED = 'INFORMATION_FETCH/SUCCEEDED',
}
export class LoadEmployeeInformation implements Action {
readonly type = ActionTypes.LOAD_EMPLOYEE_INFORMATION;
constructor() { }
}
export class InformationFetchSucceeded implements Action {
readonly type = ActionTypes.INFORMATION_FETCH_SUCCEEDED;
constructor(public payload: IEmployee[]) { }
}
export type EmployeeApiActions = LoadEmployeeInformation
| InformationFetchSucceeded;

For the explanation you can refer to my previous articles.

reducer.ts

In the above file we create a default initial state that we can use in reducer function, Interface for initial state, reducer-mapper function, some default selectors and reducer function.

Reducer function here, is accepting 2 arguments “type” and “state”, on basis of type, our switch statement will execute, and on the basis of that we can update our store and can return a new state.

Line 51 to 58 :

we are using some default function of adapter and exposing them to use as selector. For example, “selectEntites” which is exposing as selectEmployeeEntites which will help you to select on employee feature from big object i.e. store.

For eg:

state: {employee: datahr:data}

hence entity will return you only “employee: data”.

let’s see how , In selector.ts update the code as :

so we created some selectors using reference method or predefined methods in selector.ts for example, getAllEmployeeEntitesSelector. Which is again using the same selector as input parameter, the one we created in reducer file.

Now the last thing is to create an employee-store.module.ts and inject the required dependency to it as :

import { CommonModule } from '@angular/common';import { NgModule } from '@angular/core';import { EffectsModule } from '@ngrx/effects';import { StoreModule } from '@ngrx/store';import { EmployeeReducerModule } from './Reducer/employee.reducer';import { employeeFeature } from './Selector/employee.selector';import { EmployeeAPIEffects } from './Effects/employee.effect';@NgModule({imports: [...StoreModule.forFeature(employeeFeature,EmployeeReducerModule),EffectsModule.forFeature([EmployeeAPIEffects]),],})export class EmployeeStoreModule { }

and in the app.module.ts , import this module as

imports: [...EmployeeStoreModule,...],

and we are done. Now we can use the employee store as :

export class HomeComponent  {employeeData$: Observable<IEmployee[]>constructor(public store: Store<IEmployee>) {this.employeeData$ = this.store.select(getAllEmployeesSelector);}}

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -

//home.component.html<ul><li *ngFor="let employee of (employeeData$ | async)"><a href="#">{{employee.name}}</a></li></ul>

and……. run your application.

you can see your localhost:4200 as

you can also see the magic in redux devtool as

that’s it. I’ll continue CRUD in my next upcoming article. Stay tune.

I hope that you’ll like my article. Please appraise me with your feedback.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade