Home > Enterprise >  Ngrx in angular
Ngrx in angular

Time:11-17

I'm facing a problem then when i call dispatch the data isn't actually being stored, it may be a silly mistake but im new so cant find it

This is my store, User is an interface i set up in another file

import { Action } from '@ngrx/store';
import { User } from '../../interfaces/User';

export interface Appstate {
  user: User;
}

export interface ActionWithPayload<T> extends Action {
  payload: T;
}

export const initialState: Appstate = {
  user: null
};

export const Actions = {
  USER_SET: 'USER_SET',
  USER_UPDATED: 'USER_UPDATED',
  USER_DELETED: 'USER_DELETED'
};

export const userReducer = (state: Appstate = initialState, action: ActionWithPayload<User>): Appstate => {
  switch (action.type) {
    case Actions.USER_SET:
      return {
        ...state,
        user: action.payload
      };
    case Actions.USER_UPDATED:
      return {
        ...state,
        user: action.payload
      };
    case Actions.USER_DELETED:
      return {
        ...state,
        user: null
      };
    default:
      return state;
  }
};

And here is where im calling it, I'm selecting the user to check it the data is being stored its returning undefined:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from 'src/app/services/auth/auth.service';
import { User } from './../../interfaces/User';
import { Store } from '@ngrx/store';
import { Appstate, Actions } from 'src/app/state/store';
import * as Rx from 'rxjs';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {
  email: string;
  password: string;
  error: string;

  constructor(private authService: AuthService, private router: Router, private store: Store<Appstate>) { }

  ngOnInit() { }

  login() {
    if (this.email === '' && this.password === '') {
      this.error = 'Please fill all fields!';
      return;
    }
    this.error = '';
    this.authService.login(this.email, this.password).subscribe(
      (data) => {
        this.storeUser(data.user);
        this.router.navigate(['/main']);
      }, (error) => {
        if (error?.error.message === 'Unauthorized') {
          this.error = 'Wrong email or password!';
          return;
        }
        if (error?.error.message === 'You are banned') {
          this.error = 'You are banned!';
          return;
        }
      });
  }

  storeUser(user: User) {
    this.store.dispatch({
      type: Actions.USER_SET,
      payload: user
    });
    this.store.select('user').subscribe((data) => {
      console.log('data: ', data);
    }, (error) => {
      console.log('error: ', error);
    }, () => {
      console.log('completed');
    });
  }
}

CodePudding user response:

Your State Might be like as below :

import { Action } from '@ngrx/store';
import { User } from '../../interfaces/User';    
export interface Appstate {
  user: User;
}
export const initialState: Appstate = {
  user : null
}

Your Action

import { createAction, props } from "@ngrx/store";
import { User } from '../../interfaces/User';


export const SET_LOGIN_SUCCESS = '[SET_LOGIN_SUCCESS]';


export const setLoginInfo = createAction(
  SET_LOGIN_SUCCESS,
  props<{ user: User }>()
);

Your Selector

import { Appstate } from '../appState.state';
import { createFeatureSelector, createSelector } from '@ngrx/store';
export const AXS_LOGIN_USER_STATE_NAME = 'LOGIN_USER';

const getLoginUserState = createFeatureSelector<Appstate>(AXS_LOGIN_USER_STATE_NAME);
export const getLoginUser = createSelector(Appstate, (state) => {
  return state.user;
});

Your Reducer

import { createReducer, on } from "@ngrx/store";
import { setLoginInfo } from "../appAction.action";
import { initialState } from "../appState.state";

const _LoginUserReducer = createReducer(
  initialState,
  on(setLoginInfo, (state, action) => {
    return {
      ...state,
      user: action.user,
    };
  }),
);
export function LoginUserReducer(state: any, action: any) {
  return _LoginUserReducer(state, action);
}

Your component from where try to store data. LoginPage

storeUser(user: User) {
    // setLoginInfo is action
    this.store.dispatch(setLoginInfo({ user: user }));
    
    // getLoginUser is selector.
    this.store.select(getLoginUser).subscribe((data) => {
      console.log('data: ', data);
    }, (error) => {
      console.log('error: ', error);
    }, () => {
      console.log('completed');
    });
  }

might be way of implementation is different but given code work perfectly.

  • Related