Angular NgRx Setup with Simple Example using Node Js API (Learn it in 21 Steps)

Angular NgRx Setup with Simple Example using Node Js API (Learn it in 21 Steps)

  1. Create an angular project with the below command.

ng new angular-ngrx-simple-example

2. After successful creation of the angular app, change the file directory to project-name. “cd angular-ngrx-simple-example”

Open project in vs code using “code .” in terminal or open within “vs code”. Then run the project using “ng serve” in the terminal (To avoid errors always do “npm install” before “ng serve”). Open the project in chrome using [***localhost:4200***](http://localhost:4200/)

3. Open “app.component.html” in vs code and remove the content which is created by “angular CLI” while creating the app.

4. For adding “NgRx library” by using the command and install all libraries along with “**@ngrx/Store” like @ngrx/effects @ngrx/store-devtools @ngrx/schematics, Please find the command below.

* Install all in once

npm install @ngrx/store @ngrx/effects @ngrx/store-devtools @ngrx/schematics --save

(Or)

* Install one after another

npm install @ngrx/store
npm install @ngrx/effects
npm install @ngrx/store-devtools
npm install @ngrx/schematics

5. Change default “angular cli” to“ NgRx cli ”to install actions, reducers, and effects. Don’t worry it won’t affect any angular-related commands.

ng config cli.defaultCollection @ngrx/schematics

6. To generate store, state, and reducers setup please run the below command and give the root module to “app.module.ts”.

ng generate store UserState — root — module app.module.ts

7. After executing the above command reducers folder will be created and the “index.js” file will be there.

project directory

And Also Inside the “app.module.ts” file imports array is updated with new lines of code as I mentioned in the yellow-colored text below the image.

app.module.ts

The auto-generated “index.js” file will be like the below. In this “index.js” the state and reducer will be added by default after performing the above command.

reducers/index.js

reducers/index.js

8. Please run the below commands to generate actions, effects, selectors, and reducers.

ng generate action actions/users
ng generate reducer reducers/users
ng generate effect effects/users
ng generate selector selectors/users

Attached screenshot of the terminal window in which I ran the commands to generate action, effects, selectors, and reducers

terminal screen

9. So the NgRx schematics are generated automatically with a few files contains with sample data, Please find below the files.

  • Actions are in the sense calling the actions like run, catch, drop. For this project, we need users’ data so I created loadUsers to get the users and loadUsersSuccess for storing data, and loadUsersFailure action to store the error.

users.actions.ts

  • Effects are like interceptors/listeners whenever we are dispatching the action. At that time effect will be triggered and it will call the service, If the service gives a response we will call the success action. If it returns an error we will call the failure action.

users.effects.ts

  • Reducers are mainly used for updating the store based on the actions.

users.reducer.ts

  • Selectors are used to get the data from the updated state. the updated state will be available on the side of the reducer.

users.selectors.ts

10. After successfully generating all the files. Create user models for user state in app/store/models/ folder.

users.model.ts

After completing this, please do “npm install” and after running the application by using “ng serve”.

If in case any error is found while running the application please open the “package.json” file. Check the “NgRx versions” and “angular version” is the same or not. If it is not the same please change the version like below. If no errors this process is not required.

package.json before and after

After that check the app.module.ts file and change the effect statement forFeature to forRoot like below.

app.module.ts

11. Open app.module.ts and add below statement in the side imports array to load redux dev tools in the application local environment. If it is already available, Please ignore this point.

!environment. production? StoreDevtoolsModule.instrument() : []

If you don’t know how to install chrome dev tools click on this link and click on add to chrome. If already did this one please ignore it.

Open the project by using “localhost:4200” and inspecting it you can able to see redux dev-tools with no state information.

12. Open the “users.action.ts” file and add the below actions. If the “ng generate action actions/users” command generated actions by default, you can ignore this step. If you want to add new actions you can use them.

users.actions.ts

13. Open the “index.ts” file from “app/store/reducers” and add the below changes.

  • First, import the user reducer in index.js by using the below statement.

import * as fromUserReducer from ‘./users.reducer’;

  • Add State of userReducer in state interface like below. In the same way, we can add multiple states as of now we are adding only one.

export interface State { users : fromUserReducer.State}

  • Add reducer in ActionReducerMap, the same way we can add multiple reducers as of now we are adding only one.

export const reducers: ActionReducerMap = {users: fromUserReducer.reducer };

Please find the overall file for the test if you miss the code.

index.js

After successfully adding the above step you can able see the changes in the redux dev tools, For that, you need to run the application and go chrome dev tool so that you can able to see the redux tab and you will see the empty state object.

14. Open the “users.reducers.ts ”file and add the below changes.

  • Import user’s actions by using the below statement in the side “users.reducers.ts” file.

import * as UserActions from '../actions/users.actions'

  • Add data types in the side State interface like below.

export interface State {
users: any[],
loading : boolean,
error: any
}

  • Declare properties with default values inside the state object.

export const initialState: State = {
users: null,
loading : false,
error: null
};

  • Add actions inside the reducer function to update the state based on the action type.

export const reducer = createReducer(
initialState,
on(UserActions.loadUsersUserss, (state) => ({...state,loading: false, error:null})),
on(UserActions.loadUsersUserssSuccess, (state, { data }) => ({
...state,
users:data.users,
loading: true,
error: null
})),
on(UserActions.loadUsersUserssFailure, (state,{error}) => ({...state,loading: false, error})),
);

  • After changing all these the overall file will look like the below.

users.reducers.ts

Open the application and go to chrome dev tools click on the redux tab, You will see the three values in the side users object in redux dev tools.

Up to everything clear right, If anything did wrong please check from first.

15. Open the users.selector.ts file and add the below lines of code to read data from the store.

  • First import UserReducer by using the below statement.

import * as fromUserReducer from '../reducers/users.reducer';

  • To get the state object from userReducer please add the below statement.

export const getUsersState = createFeatureSelector('users');

  • Add the below methods to get specific data from the store.

export const loading = createSelector(
getUsersState,
(state: fromUserReducer.State) => state.loading
);

export const getUsers = createSelector(
getUsersState,
(state: fromUserReducer.State) => state.users
);

  • The Overall file looks like the below please check if you miss anything or not.

16.After all these do we need to add the changes in effects before that we need to create one service.

Create UserServie under the “apis/” folder and add the below lines of code.

  • To generate a service file please use the below command and also add HttpClientModule inside “app.module.ts”.

ng generate service apis/users.

terminal

app.module.ts

  • Open the users.service.ts file and add the below lines of code to call the service to get all users.

private headers:HttpHeaders= new HttpHeaders({
'Content-Type':'application/json',
'Accept':"application/json",
'Access-Control-Allow-Methods':'GET,POST,PUT,DELETE',
'Authorization':''
});

constructor(private http:HttpClient) { }

public loadUsers(){
return this.http.get(`
localhost:3000/public/users`,{headers :this.headers})
}

The overall file looks like the below, Please check twice if you miss anything.

17.Open the users.effect.ts file and add the below lines of code.

  • Import UsersService and add as a dependency in the constructor, Also Import User actions to mentioned inside the effects.

import { Injectable } from '[@angular/core](twitter.com/angular/core "Twitter profile for @angular/core")';
import { Actions, createEffect } from '
[@ngrx/effects](twitter.com/ngrx/effects "Twitter profile for @ngrx/effects")';
import { UsersService } from '../apis/users..service';
import * as UserActions from '../actions/users.actions';

[@Injectable](twitter.com/Injectable "Twitter profile for @Injectable")()
export class UsersEffects {
constructor(private actions$: Actions, private usersService:UsersService) {}
}

  • Create load user effect and add below lines of code inside that effect to call the service whenever the action is called and call the other actions after a response or error came from the service.

loadUsers$ = createEffect(() =>one
this.actions$.pipe(
ofType(UserActions.loadUsersUserss),
map((action: any) => action.payload),
mergeMap(() => {
return this.usersService.loadUsers().pipe(
map(data => UserActions.loadUsersUserssSuccess({ data })),
catchError(error => of(UserActions.loadUsersUserssFailure({ error })))
);
})
)
)

  • The Overall file looks like the one below.

18.Finally we completed all the parts of code related to NgRx Store except dispatching the action and showing data in the UI.

19. Open the “app.component.ts” file, To load data and display data in the component. Please add the below lines of code.

  • Import store form store module and add it as a dependency in the constructor by using the below lines of code.

import { Component } from '[@angular/core](twitter.com/angular/core "Twitter profile for @angular/core")';
import { Store } from '
[@ngrx/store](twitter.com/ngrx/store "Twitter profile for @ngrx/store")';

[@Component](twitter.com/Component "Twitter profile for @Component")({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'angular-ngrx-simple-example';
constructor( private readonly store: Store){}
}

  • Import user actions by using the below statements.

import * as UserActions from "./actions/users.actions";

  • To call the action by using dispatch as below.

constructor( private readonly store: Store){
this.store.dispatch(UserActions.loadUsersUserss());
}

  • After that import selectors by using the below statement and declare the users$ variable to store data.

import { Component, OnInit } from '[@angular/core](twitter.com/angular/core "Twitter profile for @angular/core")';
import { Store } from '
[@ngrx/store](twitter.com/ngrx/store "Twitter profile for @ngrx/store")';
import * as UserActions from "./actions/users.actions";
import * as UserSelectors from "./selectors/users.selectors";

[@Component](twitter.com/Component "Twitter profile for @Component")({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit{
title = 'angular-ngrx-simple-example';
users$: any;

constructor( private readonly store: Store){
this.store.dispatch(UserActions.loadUsersUserss());
}

ngOnInit(): void {
this.users$ = this.store.select(UserSelectors.getUsers);
}
}

Once all the above points are completed, Open the application in the browser and inspect the browser window click on the redux tab, You can able to see the data inside redux dev tools as below.

20. So we have data in the store but we are not able to see the data on a screen, For that, we need to add some code inside HTML also.

Open app.component.html and add the below lines of code to display the data.


List of Users ({{users.length}})




  • {{user.firstName}} {{user.secondName}}
    (@{{user.userName}})


21. Hmmm !!! Finally, I saw data in the browser and I observed the api is called and data is stored inside the store. Get the data from the store by using selectors.

Output screen #1

Output Screen #2:

Source:

Frontend: github.com/mryenagandula/angular-ngrx-simpl..

Backend: github.com/mryenagandula/Letstalk-Backend

Live Backend URI: letstalk-be.herokuapp.com

Stack blitz Project Preview: stackblitz.com/edit/angular-ngrx-simple-exa..

Thanks for reading my article, Please share your feedback, claps, and comments. In that way, it will be helped me to improve my articles in the future. Please share my story with your near and dear, Also follow and subscribe to the medium.