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 payload: User) { }
}
export class AddUser implements Action {
readonly type = ADD_USER;
constructor(public payload: User) { }
}
export class GetAllUser {
readonly type = GET_ALL_USER;
constructor() { }
}
export class AddAllUser {
readonly type = ADD_ALL_USER;
constructor(public payload: User[]) { }
}
export class StartUpdateUser implements Action {
readonly type = START_UPDATE_USER;
constructor(public payload: User) { }
}
export class UpdateUser implements Action {
readonly type = UPDATE_USER;
constructor(public payload: User) { }
}
export class StartDeleteUser implements Action {
readonly type = START_DELETE_USER;
constructor(public payload: number) { }
}
export class DeleteUser implements Action {
readonly type = DELETE_USER;
constructor(public payload: number) { }
}
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 { Actions, ofType, Effect } from '@ngrx/effects';
import { User } from '../user/user';
import { switchMap, catchError, tap, map } from 'rxjs/operators';
import * as UserActions from './user.actions';
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
@Injectable()
export class HomeEffect {
baseUrl: string = 'http://localhost:8080';
constructor(
private httpClient: HttpClient,
private actions$: Actions
) { }
@Effect()
getUsers = this.actions$.pipe(
ofType(UserActions.GET_ALL_USER),
switchMap((actionData: UserActions.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((actionData: UserActions.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 { Effect, Actions, ofType } from '@ngrx/effects';
import { switchMap, catchError, map } from 'rxjs/operators';
import { of } from 'rxjs';
@Injectable()
export class SecondPageEffect {
baseUrl: string = 'http://localhost:8080'
constructor(
private httpClient: HttpClient,
private actions$: Actions
) {
}
@Effect()
addUser = this.actions$.pipe(
ofType(UserActions.START_ADD_USER),
switchMap((actionData: UserActions.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((actionData: UserActions.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
Post a Comment