So we have this ordinary effect doSomething
. What is the official way to dispatch another action, named doSomethingElse
? The documentation doesn't really say anything about the right way. In the end there might not be much difference, yet I don't really like the fact I could use dispatch: false
in like 95% of my codebase.
Dispatching action by using dispatch: false
:
doSomething$ = createEffect(() =>
this.actions$.pipe(
ofType(AuthActions.doSomething),
map(() => AuthActions.doSomethingElse())
));
doSomethingElse$ = createEffect(
() =>
this.actions$.pipe(
ofType(AuthActions.doSomethingElse),
tap(() => console.log('it works!'))
),
{ dispatch: false });
Dispatching action without dispatch: false
:
doSomething$ = createEffect(
() =>
this.actions$.pipe(
ofType(AuthActions.doSomething),
tap(() => {
this.store.dispatch(AuthActions.doSomethingElse());
})
),
{ dispatch: false });
doSomethingElse$ = createEffect(
() =>
this.actions$.pipe(
ofType(AuthActions.doSomethingElse),
tap(() => console.log('it works!'))
),
{ dispatch: false });
Both solutions work, yet I am not sure which is the correct way of using NgRx.
Second one is not recommended.
The following code would complain if you didn't map to an action whereas putting { dispatch: false }
removes this check and should only be used for side effects like navigation, setting localStorage etc.
doSomething$ = createEffect(() =>
this.actions$.pipe(
ofType(AuthActions.doSomething),
map(() => AuthActions.doSomethingElse())
));
Your example isn't clear on why two actions are needed where one would do.
If you want a general action logger the following will work:
/**
* Log all actions in the console
*/
export function logger(
reducer: ActionReducer<RootStoreState.State>
): ActionReducer<RootStoreState.State> {
return (state, action) => {
const result = reducer(state, action);
if (action.type.startsWith("[")) { <----FILTER TO ONLY USER CREATED ACTIONS (i.e. not router)---------
console.groupCollapsed(action.type);
console.log("prev state", state);
console.log("action", action);
console.log("next state", result);
console.groupEnd();
}
return result;
};
}
and in app.module.ts
export const metaReducers: MetaReducer<any>[] = !environment.production
? [logger]
: [];
@NgModule({
imports: [
...
StoreModule.forRoot(ROOT_REDUCERS, {
metaReducers, <--------------------------------------KEY LINE-----------
runtimeChecks: {
strictStateImmutability: true,
strictActionImmutability: true,
strictStateSerializability: true,
strictActionSerializability: true
}
}),
...