Search code examples
angularreduxngrxngrx-storengrx-effects

NGRX Ionic : createReducer is calling all actions


Environment: Ionic 6, Angular 13.

Scenario: Bringing data from 1 API that is paginated. Trying to build another action that change the page, bring new data and collect all them.

Issue: Data are coming fine from API, after action is dispatched.

this.store.dispatch(UsersActions.loadFilteredUsers(req));

After declaring another case of an action on reducer.ts file it is running despite no action is dispatched for that.

Actions.ts file

export const loadFilteredUsers = createAction(
  "[Fileterd Users] Load",
  props<{ userFiltered: IUsersFilteredRequest }>()
);

export const loadFilteredUsersSuccess = createAction(
  "[Fileterd Users] Success",
  props<{ userFiltered: any }>()
);

export const loadFilteredUsersFailure = createAction(
  "[Fileterd Users] Fail",
  props<{ error: string }>()
);

export const loadMoreUsers = createAction(
  "[Fileterd Users] Success",
  props<{ userFiltered: IUsersFilteredRequest }>()
);

Effects.ts file

  loadfilteredUsers$ = createEffect(() => {
    return this.actions$.pipe(
      ofType(UsersActions.loadFilteredUsers),
      switchMap((data: any) =>
        this.filterUserservice.filterUserOntime(data).pipe(
          map((userFiltered) =>
            UsersActions.loadFilteredUsersSuccess({ userFiltered })
          ),
          catchError((error) =>
            of(UsersActions.loadFilteredUsersFailure({ error }))
          ),
          shareReplay(1)
        )
      )
    );
  });

Reducer.ts file

export const UsersFileterdReducer = createReducer<UsersFilteredState>(
  initialState,
  on(
    UsersActions.loadFilteredUsersSuccess,
    (state, action): UsersFilteredState => {
      return {
        ...state,
        userFiltered: action.userFiltered,
        error: "",
      };
    }
  ),
  on(
    UsersActions.loadFilteredUsersFailure,
    (state, action): UsersFilteredState => {
      return {
        ...state,
        userFiltered: [],
        error: action.error,
      };
    }
  ),
  on(UsersActions.loadMoreUsers, (state, action): UsersFilteredState => {
    console.log("loadMoreUsers", action, "satet", state);
    return {
      ...state,
      // userFiltered: [...state.userFiltered["response"], action.userFiltered],
    };
  })
);

Tried to add also runtimeChacks for immutability but no changes. strictStateImmutability: true ... ect

Configuration at app.module.ts and at tabs.module.ts

--------app.module.ts-------------------
     StoreModule.forRoot({}),
    EffectsModule.forRoot([]),

------- tabs.module.ts -------------
    StoreModule.forFeature("UsersFileterdReducer", UsersFileterdReducer),
    EffectsModule.forFeature([UserPersonalffects]),

The issue start directly when add on reducer the case for loadMoreUsers, where is starting despite im not calling any action for that.


Solution

  • Actions are determined by their type. You can't have two actions with the same type string. That's also kinda the whole point: actions should be single-source-single-goal. Modify the type string and it will work.