NGRX - STATE MANAGE WITH REDUX PATTERN IN ANGULAR JS APPLICATION

  • Link source code kit: kit-ngrx

  • Create new angular application with angular CLI

  • Install dependency packages:
    • npm install @ngrx/store @ngrx/effects @ngrx/store/devtools --save
  • Model:

    • Create folder models and file: user.model.ts
    • export interface User {
          login: string;
          id: string;
      }
      
  • ACTIONS:

    • Create actions folder, and file users.action.ts
    • Actions: LoadUser, LoadUserSuccess (callback function), DeleteUser, EditUser, AddUser

    • import { User } from '../models/user.model';
      
      export const LOAD_USER = 'LOAD_USER';
      export const LOAD_USER_SUCCESS = '';
      export const ADD_USER = 'ADD_USER';
      export const EDIT_USER = 'EDIT_USER';
      export const DELETE_USER = 'DELETE_USER';
      
      export class LoadUser {
          readonly type = LOAD_USER;
          constructor() { }
      }
      export class LoadUserSuccess {
          readonly type = LOAD_USER_SUCCESS;
          constructor(public payload: User[]) { }
      }
      export class AddUser {
          readonly type = ADD_USER;
          constructor(public payload: User) { }
      }
      export class DeleteUser {
          readonly type = DELETE_USER;
          constructor(public payload: number) { }
      }
      export class EditUser {
          readonly type = EDIT_USER;
          constructor(public index: number, public payload: User) { }
      }
      export type Action = LoadUser | LoadUserSuccess | AddUser | DeleteUser | EditUser;
      
  • Reducer:

    • Create reducers folder and file: users.reducer.ts
    • import * as UserActions from '../actions/users.actions';
      import { User } from '../models/user.model';
      
      export function UserReducer(state: User[] = [], action: UserActions.Action) {
          switch (action.type) {
              case UserActions.LOAD_USER_SUCCESS:
                  return action.payload;
              case UserActions.ADD_USER:
                  return [...state, action.payload];
              case UserActions.DELETE_USER:
                  state.splice(action.payload);
                  return state;
              case UserActions.EDIT_USER:
                  state[action.index] = action.payload;
                  return state;
              default:
                  return state;
          }
      }
      
  • Effects:

    • To dispatch action with other actions such as: services,...

    • Create folder effects and file: users.effect.ts

    • ```
      import { Injectable } from '@angular/core';
      import {Actions, Effect} from '@ngrx/effects';
      import 'rxjs/add/operator/switchMap';
      import 'rxjs/add/operator/map';

      import * as UserActions from '../actions/users.actions';
      import { UserService } from '../services/user.service';
      import { User } from '../models/user.model';
      import { Observable } from 'rxjs/Observable';

      @Injectable()
      export class UserEffects {

      constructor\(  
          private actions$: Actions,  
          private userService: UserService  
      \) {}
      
      @Effect() LoadUser$ = this.actions$.ofType(UserActions.LOAD_USER)
          .switchMap((action) => this.userService.getUser().map((users: User[]) => new UserActions.LoadUserSuccess(users)));
      

      }

      ```

  • Service will return Observable<User[]> object

    • getUser() {
          const url = 'https://api.github.com/users?since=1&access_token=a87b8ff614b96bd43edb26f9ba056abf89e6decc';
          return this.http.get(url).map(res => res.json());
        }
      
  • App State

    • Contains all state of application:

    • Create a file: app.state.ts

      • import { User } from './models/user.model';
        
        export interface AppState {
            readonly users: User[];
        }
        
  • Define StoreModule and EffectModule in app.module.ts

    • const store = {
        users: UserReducer
      };
      
      @NgModule({
        ........
        imports: [
          ....
          StoreModule.forRoot(store),
          EffectsModule.forRoot([UserEffects])
        ],
        ......
      })
      
  • Use in component

    • export class UserComponent implements OnInit {
        users: Observable<User[]>;
      
      //Inject  store
        constructor(private store: Store<AppState>) {
          this.users = this.store.select('users');
          this.store.dispatch(new userActions.LoadUser()); // dispatch load user
        }
      
        ngOnInit() {
        }
      
      }
      

results matching ""

    No results matching ""