I have an Ionic 3 App where I use ngrx/store and ngrx/effects for side effect or async actions. Everything works fine but there is one little problem.
When should I call the error or success message after dispatching a action. I know that the effect job is to dispatch another action base on a dispatched action from the component. But where should I put it?
Here is my sample below of my reducer.ts
mport { LOGIN_REQUEST, LOGIN_FAILED, LOGIN_SUCCESS } from './../actions/authenticate';
import { AuthState } from './../store';
import { Action } from '@ngrx/store';
import { PostState } from '../store';
const initialState: AuthState = {
isAuthenticated: false,
authenticating: false,
token: null,
error: null
}
export function authReducer(state = initialState, action: Action) {
switch (action.type) {
case LOGIN_REQUEST:
return {
...state,
authenticating: true,
// USERS: (<any>action).data.USERS
}
case LOGIN_SUCCESS:
return {
...state,
authenticating: false,
isAuthenticated: true,
token: (<any>action).payload.data.token
}
case LOGIN_FAILED:
return {
...state,
authenticating: false,
error: (<any>action).payload
}
default:
return state;
}
}
and in my effects.ts
@Effect()
authenticate$ = this.actions$.ofType(authActions.LOGIN_REQUEST)
.pipe(
switchMap((data: any) => {
return this.authApi.signIn(data.payload).pipe(
map((response: any) => ({ type: authActions.LOGIN_SUCCESS, payload: response })),
catchError(error => of({ type: authActions.LOGIN_FAILED, payload: error }))
)
})
)
In my app.module
imports: [
...
StoreModule.forRoot(rootReducer, { metaReducers }),
EffectsModule.forRoot(effects),
StoreDevtoolsModule.instrument({
maxAge: 5
})
],
and finally in my component.ts
ionViewWillEnter() {
this.store.select<any>('auth').subscribe(state => {
this.auth = state
if (state.error) this.displayErrorMessage()
})
}
displayErrorMessage() {
const toast = this.toastCtrl.create({
message: 'Error occured',
duration: 3000,
position: 'top'
});
toast.onDidDismiss(() => {
console.log('Dismissed toast');
});
toast.present();
}
If you are familiar with redux you knew that you would understand the code above in the reducers and effects. Everything is working fine but I think there is a little problem in my component on when to call a success or error message? Should I call it instead in the effect? But How?
Appreciate if someone could help with code sample. Thanks in advance.
You could inject ActionsSubject
into the component and listen for success or failed actions, but I wouldn't recommend this.
Instead also use effects to show notifications, e.g. with an angular material snackbar:
@Effect({ dispatch: false })
error = this.actions.pipe(
ofType<ServerError>(ActionTypes.ServerError),
map(({ payload }) => {
this.snackBar.open(payload.message, 'Close');
})
)
For more info see Start using ngrx/effects for this