1

What is the best way to reset the entire state when we have different reducers? I am having problems with this when I use selectors, since it does not bring me the initial state when I do the reset

MetaReducer

import { ActionReducer } from '@ngrx/store';
import { UserActionTypes } from '../../actions/actionTypes';

export function clearStateReducer(reducer: ActionReducer<any>): ActionReducer<any> {
  return (state, action) => {
    if (action.type === UserActionTypes.Logout) {
      state = undefined;
    }
    return reducer(state, action);
  };
}

State Module

import { NgModule } from '@angular/core';
import { StateService } from './state.service';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { StoreModule } from '@ngrx/store';
import { appReducer } from './reducers';
import { getInitialState } from './state';
import { metaReducers } from './reducers/metaReducers';

@NgModule({
  imports: [
    StoreModule.forRoot(appReducer, {
      initialState: getInitialState(),
      metaReducers,
      runtimeChecks: {
        strictStateImmutability: false,
        strictActionImmutability: false,
        strictStateSerializability: false,
        strictActionSerializability: false
      }
    }),
    StoreDevtoolsModule.instrument({
      maxAge: 25
    })
  ],
  providers: [StateService]
})
export class StateServiceModule {}
  • What is your current approach? – Jota.Toledo Sep 26 '19 at 09:25
  • Refreshing the page will start the app with initial ngrx state. Other than that you probably want to use meta-reducer. Third option is to add a new action and new case for each reducer and trigger them all from resetState$ effect. – codeepic Sep 26 '19 at 09:27
  • Can you share your code in stackblitz? Are you using localstorage ? – rijin Sep 26 '19 at 09:29
  • Im using this metaReducer - export function clearStateReducer(reducer: ActionReducer): ActionReducer { return (state, action) => { if (action.type === UserActionTypes.Logout) { state = undefined; } return reducer(state, action); }; } – José Francisco Vargas Galán Sep 26 '19 at 09:29
  • @Jose So what's the problem then - it should reset the whole state. – codeepic Sep 26 '19 at 09:31
  • More explanations about how to do it using meta-reducer here https://stackoverflow.com/questions/39323285/how-to-reset-all-states-of-ngrx-store and here https://stackoverflow.com/questions/39323285/how-to-reset-all-states-of-ngrx-store/45324038#45324038 – codeepic Sep 26 '19 at 09:33
  • The problem is that after resetting, when I call a selector it returns the value before the reset – José Francisco Vargas Galán Sep 26 '19 at 09:33
  • @Jose if you can confirm that the state is really reset, but you are still getting the previous state when using selectors, it's because the selectors are memoized (they store the result of the previous call in cache, so if you pass the same params, the memoized function doesn't run the computation but returns the computed result stored in its cache). There is a way to reset ngrx selectors by running `selectorName.release()`. More about that on https://ngrx.io/guide/store/selectors#resetting-memoized-selectors – codeepic Sep 26 '19 at 09:37
  • Perfect @codeepic when should i use it then? Sorry but im new in ngrx – José Francisco Vargas Galán Sep 26 '19 at 09:41
  • This I don't know for sure and the docs are lacking. But selectors are just functions, you usually use them either in effects or in components, when subscribing to pieces of state inside `state.pipe(...` method. But you should be able to use them anywhere. In that case I would call `.release()` method on each selector from inside `if (action.type === UserActionTypes.Logout) {` check in your meta reducer. Do let me know if it solves the issue for you. – codeepic Sep 26 '19 at 09:47
  • Unfortunately not, perhaps it is an error of the release method, since it does not reset me of any selector regardless of where I use it, equally thanks! – José Francisco Vargas Galán Sep 26 '19 at 10:08
  • OK, thanks for the update and sorry to hear it's not working for you - open a github issue then under ngrx OS project. – codeepic Sep 26 '19 at 10:20

2 Answers2

1

You can reset like this by setting the state back to the initial state

export const postReducer = createReducer(
  initialState,
  on(PostActions.ResetState, (state) => {
    return { state: initialState };
  }),
);
Tony Ngo
  • 19,166
  • 4
  • 38
  • 60
0

You may not assign state, instead call the reducer with undefined:

export function clearStateReducer(reducer: ActionReducer<any>): ActionReducer<any> {
  return (state, action) => {
    if (action.type === UserActionTypes.Logout) {
      return reducer(undefined, action);
    }
    return reducer(state, action);
  };
}
timdeschryver
  • 14,415
  • 1
  • 19
  • 32