I am trying to write an effect for an action but it is throwing an error as: “Effect “n.loadInfo$” dispatched an invalid action: null Error“
I have my effect as below:
@Effect()
loadInfo$ =
this.actions.ofType(fromHeaderActions.EInfoActions.OPEN_INFO).pipe(
withLatestFrom(
this.store.select(fromSelectors.GetINFOPayload)),
switchMap(([action, infoPayLoad]) => {
let cAction: fromHeaderActions.OpenINFOWIdget =
<fromHeaderActions.OpenINFOWIdget>action;
return this.infoService.loadINFO(infoPayLoad).pipe(
// Dispatch success action
map(response => new
fromHeaderActions.OpenINFOWIdgetSuccess(response)),
catchError(error => {
return of(new
fromHeaderActions.OpenINFOWIdgetFail(error.message))
})
)
})
);
I have my action defined as below:
export class OpenINFOWIdget extends BaseGetDetailsAction implements Action {
readonly type = EInfoActions.OPEN_INFO;
constructor() {
super();
}
}
//added action after the comment
export class OpenINFOWIdgetSuccess extends BaseGetDetailsAction
implements Action {
readonly type = EInfoHeaderActions.OPEN_INFO_SUCCESS;
constructor(public payload: INFO) {
super();
}
}
export class OpenINFOWIdget extends BaseGetDetailsAction implements Action {
readonly type = EInfoActions.OPEN_INFO_FAIL;
constructor(public payload: string) {
super();
}
}
And in the service as below:
public INFOPayloadsource = new BehaviorSubject<INFO>(initINFO);
infoPayload$ = this.INFOPayloadsource.asObservable();
private SelectedInfoSource = new Subject<INFO>();
selectedInfo$ = this.SelectedInfoSource.asObservable();
loadINFO(payload: INFO): Observable<INFO> {
if (payload != null) {
this.IsInfoEnableSource.next(true);
this.InfoPayloadsource.next(payload);
}
return this.selectedInfo$;
}
I have selector as below that is used in the effect:
export const GetINFOPayload = createSelector(getInfoState,
(state:
InfoDetailsState) => {
if (state) {
if (state.infoDetails != null &&
state.infoDetails.INFODetail !=
null &&
state.infoDetails.INFODetail.Active != null) {
let payload: INFO = { ...initINFO };
payload = state.infoDetails.INFODetail.Active;
return payload;
}
}
return null;
});
Create reducer as below after the comment:
case
fromInfoDetailsHeaderActions.EInfoHeaderActions.OPEN_INFO: {
return {
...state,
IsScreenOverlay: true,
IsEditable: false
}
};
case fromInfoDetailsHeaderActions.EInfoHeaderActions.OPEN_INFO_SUCCESS: {
return {
...state,
IsScreenOverlay: false,
IsEditable: true
}
};
I would really appreciate if anyone can help on it. Thank you!
Advertisement
Answer
Your effect is trying to dispatch the result of this.infoService.loadINFO(), which is why you get the error saying that it is not a valid action.
You should map this to a success action instead:
@Effect()
loadInfo$ = this.actions.ofType(fromHeaderActions.EInfoActions.OPEN_INFO).pipe(
withLatestFrom(
this.store.select(fromSelectors.GetINFOPayload)
),
switchMap(([action, infoPayLoad]) => {
let cAction: fromHeaderActions.OpenINFOWIdget = <fromHeaderActions.OpenINFOWIdget>action;
return this.infoService.loadINFO(infoPayLoad).pipe(
// Dispatch success action
map(response => new fromHeaderActions.OpenINFOWIdgetSuccess(response)),
catchError(error => {
return of(new fromHeaderActions.OpenINFOWIdgetFail(error.message))
})
)
})
);
You will also need to add the corresponding action and handle it in your reducer, if necessary.