Skip to content
Advertisement

Getting error Effect “n.loadInfo$” dispatched an invalid action

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.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement