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!
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.