NgRx effects (Rest-Http calls) implementation


 When we are working with client-side state management with the help of NgRx, we need to implement effects to make Http or rest calls.

Hey guys, in the previous post we have successfully implemented the state management with NgRx and in this post we are going see how to manage the Http calls or rest call in the NgRx environment.

Effects – Effects is the solution to manage the rest calls in NgRx environment.

[at the bottom of the post you will get the link to download the project]
[ If you are preparing for an interview please click here - angular interview questions and answers ]  

Let’s do it step by step.

We are going to use the same example from our previous post so if you are not visited the previous post please must visit it here [NgRx basic Implementation]

At very first, install the NgRx effects.

Following is the installation command and description.
npm install –save @ngrx/effects  

D:\Angular-DemoApps\Angular 6 - ngrx- effects or rest-calls(http client) implementation> npm install @ngrx/effects --save
npm WARN @ngrx/store@8.2.0 requires a peer of @angular/core@^8.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN @ngrx/store@8.2.0 requires a peer of rxjs@^6.4.0 but none is installed. You must install peer dependencies yourself.
npm WARN bootstrap@4.2.1 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself.      
npm WARN bootstrap@4.2.1 requires a peer of popper.js@^1.14.6 but none is installed. You must install peer dependencies yourself.     
npm WARN @ngrx/effects@8.5.0 requires a peer of @angular/core@^8.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN @ngrx/effects@8.5.0 requires a peer of @ngrx/store@8.5.0 but none is installed. You must install peer dependencies yourself. 
npm WARN @ngrx/effects@8.5.0 requires a peer of rxjs@^6.4.0 but none is installed. You must install peer dependencies yourself.       
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ @ngrx/effects@8.5.0
updated 1 package and audited 40187 packages in 27.116s

After completing the installation, we are going to add a few actions in user action page so we can get working with effects.

user.actions.ts
import { Action } from '@ngrx/store';
import { User } from 'src/app/user/user';

export const START_ADD_USER = '[second page] start add user';
export const ADD_USER = '[second page] add user';

export const GET_ALL_USER = '[second page] get all user';
export const ADD_ALL_USER = '[second page] add all user';

export const START_DELETE_USER = '[second page] start delete user';
export const DELETE_USER = '[second page] delete user';

export const START_UPDATE_USER = '[second page] start update user';
export const UPDATE_USER = '[second page] update user';

export class StartAddUser implements Action {
    readonly type = START_ADD_USER;
    constructor(public payloadUser) { }
}
export class AddUser implements Action {
    readonly type = ADD_USER;
    constructor(public payloadUser) { }
}

export class GetAllUser {
    readonly type = GET_ALL_USER;
    constructor() { }
}
export class AddAllUser {
    readonly type = ADD_ALL_USER;
    constructor(public payloadUser[]) { }
}

export class StartUpdateUser implements Action {
    readonly type = START_UPDATE_USER;
    constructor(public payloadUser) { }
}
export class UpdateUser implements Action {
    readonly type = UPDATE_USER;
    constructor(public payloadUser) { }
}

export class StartDeleteUser implements Action {
    readonly type = START_DELETE_USER;
    constructor(public payloadnumber) { }
}
export class DeleteUser implements Action {
    readonly type = DELETE_USER;
    constructor(public payloadnumber) { }
}


export type userListActions =
    | StartAddUser
    | AddUser

    | GetAllUser
    | AddAllUser

    | StartDeleteUser
    | DeleteUser

    | StartUpdateUser
    | UpdateUser
    ;


Here we have added a few extra actions like StartAddUser, StartDeleteUser and StartUpdateUser etc, so we can identify when to make a call to the server(rest/HTTP call) and after that, we can call next action like addUser, DeleteUser and UpdateUse respectively, which already have a logic of same.


To have an idea of how different effects work together we have created two files, one for home and another for registration page which is home.effects.ts and second-page.effects.ts  respectively.

home.effects.ts
import { HttpClient } from '@angular/common/http';
import { ActionsofTypeEffect } from '@ngrx/effects';
import { User } from '../user/user';
import { switchMapcatchErrortapmap } from 'rxjs/operators';

import * as UserActions from './user.actions';
import { Injectable } from '@angular/core';
import { of } from 'rxjs';

@Injectable()
export class HomeEffect {

  baseUrlstring = 'http://localhost:8080';

  constructor(
    private httpClientHttpClient,
    private actions$Actions
  ) { }

  @Effect()
  getUsers = this.actions$.pipe(
    ofType(UserActions.GET_ALL_USER),
    switchMap((actionDataUserActions.GetAllUser=> {
      return this.httpClient.get<User[]>(`${this.baseUrl}/userlist`).pipe(
        map(responseData => {
          return new UserActions.AddAllUser(responseData);
        }),
        catchError(error => {
          return of();
        })
      )
    })
  );

  @Effect()
  deleteUsers = this.actions$.pipe(
    ofType(UserActions.START_DELETE_USER),
    switchMap((actionDataUserActions.StartDeleteUser=> {
      return this.httpClient.delete<Boolean>(`${this.baseUrl}/userlist/${actionData.payload}`).pipe(
        map(responseData => {
          if (responseData) { return new UserActions.DeleteUser(actionData.payload); }
        }),
        catchError(error => {
          return of();
        })
      );
    })
  );
}



On home page, we have two actions where we need to make a call to the server, one is get user list and another is delete user, which we have added as effect in home effects file.
Here in effect, we have caught start delete user action and made a call to the server, after that as soon as we get the response we have fired new action DeleteUser which will delete user from the client-side state.
On the second page, again we have two actions where we need to make a call to the server, one for update user and other for add user so we have added actions for the same in the second-page actions file.

second-page.effects.ts 
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { User } from '../user/user';
import * as UserActions from './user.actions';
import { EffectActionsofType } from '@ngrx/effects';
import { switchMapcatchErrormap } from 'rxjs/operators';
import { of } from 'rxjs';

@Injectable()
export class SecondPageEffect {

  baseUrlstring = 'http://localhost:8080'

  constructor(
    private httpClientHttpClient,
    private actions$Actions
  ) {
  }

  @Effect()
  addUser = this.actions$.pipe(
    ofType(UserActions.START_ADD_USER),
    switchMap((actionDataUserActions.StartAddUser=> {
      return this.httpClient.put<User>(`${this.baseUrl}/user`actionData.payload).pipe(
        map(responseData => {
          return new UserActions.AddUser(responseData);
        }),
        catchError(error => {
          return of();
        })
      )
    })
  );

  @Effect()
  updateUser = this.actions$.pipe(
    ofType(UserActions.START_UPDATE_USER),
    switchMap((actionDataUserActions.StartUpdateUser=> {
      return this.httpClient.post<User>(`${this.baseUrl}/update/user`actionData.payload).pipe(
        map(responseData => {
          return new UserActions.UpdateUser(responseData);
        }),
        catchError(error => {
          return of();
        })
      )
    })
  );

}


Here also we have implemented same as implemented on the home page for update and add user action effects.

Here is the output



And that’s it,
We have successfully implemented the effects in NgRx.

I hope you like it.

Here is the link to download [download the project]

Comments