Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngrx 8 effects dispatch action of other type

I'm reaching you here about ngrx effects, what i am tryign to do is to have a function login that distpatch an action type login and an effect on this action will user my service to make api call. After this return token, i want to dispatch two other action one of type getUserMenu and one of type getUserInfo. Those two action will be of different type and have different effect.

I have 3 stores at the end: one for token and auth one for user info one for menu info

i tried things like that :

login = createEffect(
  () =>
  this.actions$
  .pipe(
  ofType(authLogin),
    tap(action => {
    console.log("EFFECT LOGINNNN");
    return this.authService.postLogin(action.username, 
      action.password).pipe(
        map((data: any) => {
          console.log("AUTHTHHTHTH DATATA ", data);
          let props = data.token;
          let payload = {
            token: data.token,
            isAuthenticated: true
          }
      this.store.dispatch(moMenuHttpGetListAction({US_ID: action.username}));  
      this.store.dispatch(userHttpGetInfoAction({US_ID:action.username}));
      this.localStorageService.setItem(AUTH_KEY, payload);
    }))
  })
),
{ dispatch: true }
);

if i set dispatch false login work but no method called for getting user info and user menu but when i set dispatch true i have infinit loop on this same effect the action moMenuHttpGetListAction would look like that :

moMenuHttpGetListEffect = createEffect(
     () => this.actions$.pipe(
        ofType(moMenuHttpGetListAction),
        switchMap(action => {
          console.log("MOMENU LOGINNNN");

          return this.moMenuService.getKmApplications(action.US_ID).pipe(
          map((data: any) => {
            console.log("MOMENU DATATA ", data);
            console.log("MOMENU DATATA ", action.US_ID);
            let payload = {
              MO_MENU: data
            }

          this.store.dispatch(moMenuSetListAction({payload: data}));
           this.localStorageService.setItem(MENU_KEY, payload);
          }))
        })
        ),
    { dispatch: false }
  );

but on this one when i set dispatch to true , i got error compiling. and my action looks like :

import { createAction } from "@ngrx/store";
import { props } from "@ngrx/store";
import { MoMenu, MoMenuState } from "./mo_menu.models";

//TODO CHANGER ME_ID en US_ID
export const moMenuGetErrorAction = createAction("[User] Get Info");
export const moMenuGetIsLoadingAction = createAction("[User] Get Info");

export const moMenuSetErrorAction = createAction('[MoMenu] HTTP GET ACTION',
    props<{error: string}>()
    );
export const moMenuSetLoadingAction = createAction('[MoMenu] HTTP GET ACTION',
    props<{loading: boolean}>()
    );
export const moMenuHttpGetListAction = createAction('[MoMenu] HTTP GETLIST  ACTION',
    props<{US_ID: string}>()
    );
export const moMenuHttpGetListErrorAction = createAction('[MoMenu] HTTP GET ACTION Error',
    props<{error: any}>()
    );

export const moMenuGetListAction = createAction("[MoMenu] Get List");
export const moMenuSetListAction = createAction("[MoMenu] Set Mo Menu List",
    props<{payload: MoMenu[]}>());
export const moMenuDeleteAction = createAction("[MoMenu] Delete List");

those are the two reducers concerned as someone ask me to add :

Ngrx is kinda new to me so i'd love some help on this =)

import { AuthState } from './auth.models';
import { authLogin, 
  authLogout ,
  authGetErrorAction,
  authGetIsLoadingAction,
  authSetErrorAction,
  authSetIsLoadingAction
} from './auth.actions';
import { createReducer, on, Action } from '@ngrx/store';

export const initialState: AuthState = {
  isAuthenticated: false,
  token: undefined,
  isLoading: false,
  HttpResponse: undefined
};

const reducer = createReducer(
  initialState,
    on(authSetErrorAction,  (state, { error }) => ({
    ...state, HttpResponse:  error
  })),
   on(authSetIsLoadingAction,  (state, { isLoading }) => ({
    ...state, isLoading: isLoading 
  })),

  on(authLogin, state => ({ ...state, isAuthenticated: true })),
  on(authLogout, state => ({ ...state, isAuthenticated: false }))
);

export function authReducer(
  state: AuthState | undefined,
  action: Action
): AuthState {
  return reducer(state, action);
}

import { MoMenuState } from "./mo_menu.models";
import { 
  moMenuGetListAction, 
  moMenuDeleteAction,
  moMenuHttpGetListAction,
  moMenuSetListAction,
  moMenuHttpGetListErrorAction,

  moMenuGetErrorAction,
  moMenuGetIsLoadingAction,
  moMenuSetErrorAction,
  moMenuSetLoadingAction
 } from "./mo_menu.actions";
import { createReducer, on, Action } from "@ngrx/store";

export const initialState: MoMenuState = {
    isLoading: false,
  HttpResponse: undefined,
MoMenuItems: null
}

const reducer = createReducer(
  initialState,
  on(moMenuSetErrorAction,  (state, { error }) => ({
    ...state, HttpResponse:  error
  })),
   on(moMenuSetLoadingAction,  (state, { loading }) => ({
    ...state, isLoading: loading 
  })),

  on(moMenuHttpGetListErrorAction, (state, { error }) => (
    undefined)),
   on(moMenuSetListAction, (state, { payload }) => ({
    ...state, MoMenus: payload 
  })),

 on(moMenuHttpGetListAction, (state, { US_ID }) => ({
    ...state
  })),
  on(moMenuGetListAction, state => state),
  on(moMenuDeleteAction, state => state)
);

export function moMenuReducer(
  state: MoMenuState | undefined,
  action: Action
): MoMenuState {
  return reducer(state, action);
}

If some of you guys have any idea for me ?

like image 827
Razgort Avatar asked Aug 13 '19 04:08

Razgort


People also ask

What is Dispatch false in NgRx effect?

In this example, we use tap to perform the side effect itself, and pass “{dispatch: false}” to the “createEffect” function to indicate it does not need to dispatch anything after the side effect completes.

What is ofType in RXJS?

'ofType' filters an Observable of Actions into an observable of the actions whose type strings are passed to it.

What is @effect in Angular?

} ​@ngrx/effects provides an Angular actions$ service (which is also an Observable ) to emit every action that has been dispatched by your application in a single stream. Its ofType() method can be used to filter the one or more actions we're interesting in before adding a side-effect.

How do you call an effect in NgRx?

Getting started. It will add and install the @ngrx/effects library to your package. json and scaffold your AppModule to import the NgRx EffectsModule into your application. With the setup complete, we can start modifying the app to introduce and handle some API calls using Effects.


1 Answers

This is how I'm dispatching multiple actions as a result of another action in NgRx 8:

@Injectable()
export class MyEffects {
    myAction$ = createEffect(() =>
        this.actions$.pipe(
            ofType(myActions.firstAction),
            switchMap(action => this.someService.getById(action.someId)),
            switchMap((sth: Something) => [
                myActions.firstActionSuccess({ payload: sth }),
                myActions.secondAction({ payload: sth.xyz }),
                // ... more actions
            ])
        )
    );

    constructor(
        private someService: SomeService,
        private actions$: Actions
    ) { }
}

Actions look like this:

export const firstAction = createAction('First Action', props<{ someId: number }>());
export const firstActionSuccess = createAction('First Action Success', props<{ payload: Something }>());
export const secondAction = createAction('Second Action', props<{ payload: string }>());

Hope that helps!

like image 113
pschild Avatar answered Sep 24 '22 20:09

pschild