I have an Ionic 3 App where I use ngrx store and effect for a better state management library since I am developing a large application. Every data flow is working fine and smooth. But there is one little problem.
If the user has logged out in the App some of the states related to a session or user info are cleared but what I want to happen is clear all the states from every reducer.
How will I achieve this? Here is something what I did below:
in my actions-events.ts
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST';
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
export const LOGOUT_FAILED = 'LOGOUT_FAILED';
and in my component.ts
logout() {
this.store.dispatch({ type: LOGOUT_REQUEST })
}
in my effects.ts
@Effect()
deAuthenticate$ = this.actions$.ofType(authActions.LOGOUT_REQUEST)
.pipe(
switchMap(() => {
return this.authApi.signOut().pipe(
map((response: any) => ({ type: authActions.LOGOUT_SUCCESS, payload: response })),
catchError(error => of({ type: authActions.LOGOUT_FAILED, payload: error }))
)
})
)
I declared three types of actions that will be asynchronous on the first block of code. Then the component will dispatch an LOGOUT_REQUEST
action. After that the effects will listen to that action and call a method on the provider to request an http logout request on a server. I will wait for the response and dispatch a SUCCESS or FAILED action to update the state tree.
Now everything is working fine but I notice that there is a little problem that some data exist or persist in the store or some part of the state. Which I don't want to happen when another user tries to logged in.
What I want to happen is clear all the whole state tree when a user logs out. How can I do that?
For additional information about my structure here is my authReducer below
import { LOGIN_REQUEST, LOGIN_FAILED, LOGIN_SUCCESS, LOGOUT_REQUEST, LOGOUT_SUCCESS, LOGOUT_FAILED } from './../actions/authenticate';
import { AuthState } from './../store';
import { Action } from '@ngrx/store';
import { PostState } from '../store';
const initialState: AuthState = {
isAuthenticated: false,
authenticating: false,
unauthenticating: false,
token: null,
error: null
}
export function authReducer(state = initialState, action: Action) {
switch (action.type) {
case LOGIN_REQUEST: // Sign in request
return {
...state,
authenticating: true,
}
case LOGIN_SUCCESS: // Sign in success
return {
...state,
authenticating: false,
isAuthenticated: true,
token: (<any>action).payload.data.token
}
case LOGIN_FAILED: // Sign in failed
return {
...state,
authenticating: false,
error: (<any>action).payload
}
case LOGOUT_REQUEST: // Sign out request
return {
...state,
unauthenticating: true
}
case LOGOUT_SUCCESS: // Signout success
return {
...state,
unauthenticating: false,
isAuthenticated: false,
token: null
}
case LOGOUT_FAILED: // Signout failed
return {
...state,
unauthenticating: false,
error: (<any>action).payload
}
default:
return state;
}
}
and in my rootReducer
import { postsReducer } from "../reducers/posts";
import { usersReducer } from "./users";
import { authReducer } from "./authenticate";
export const rootReducer = {
posts: postsReducer,
users: usersReducer,
auth: authReducer,
}
in my app.module.ts I used a logger for logging the state tree.
export function logger(reducer: ActionReducer<any>): any {
// default, no options
return storeLogger()(reducer);
}
export const metaReducers = [logger];
and in the imports
StoreModule.forRoot(rootReducer, { metaReducers }),
EffectsModule.forRoot(effects),
StoreDevtoolsModule.instrument({
maxAge: 15
}),
Appreciate if someone could help. Thanks in advance.