在Ionic 3中的NgRx中传递错误的URL时,reducer错误始终未定义

时间:2019-05-29 19:12:15

标签: angular redux ionic3 ngrx

有人在每次出现错误时都会帮助我看看这里出了什么问题: core.js:12632 ERROR TypeError: Cannot read property 'error' of undefined

我的效果:

  @Effect() loadByEmail = this.actions
    .pipe(
      ofType(ProfileActions.ActionTypes.Begin),
      map((action: ProfileActions.LoadProfileBegin) => action),
      switchMap(action => this.service.loadByEmail(action.email, true)),
      map(response => ({
        type: ProfileActions.ActionTypes.Success,
        payload: response,
        error: null
      })),
      catchError((error) => of ({
        type: ProfileActions.ActionTypes.Failure,
        error: error
      }))
    );

减速器:

export interface ProfileState {
  payload: any;
  loading: boolean;
  error: any;
}

const initialState: ProfileState = {
  loading: false,
  error: null,
  payload: null
};

export function profileReducer(state = initialState, action: profileActions.ActionsUnion): ProfileState {
  switch (action.type) {

    case profileActions.ActionTypes.Begin: {
      return {
        ...state,
        loading: true,
        error: null
      };
    }

    case profileActions.ActionTypes.Success: {
      return {
        ...state,
        loading: false,
        payload: action.payload.data
      };
    }

    case profileActions.ActionTypes.Failure: {
      return {
        ...state,
        loading: false,
        error: action.payload.error /* this is the line 49*/
      };
    }

    default: {
      return state;
    }
  }
}

export const getProfile = (state: ProfileState) => state.payload;

我认为我可能在这里犯了一个大错误,导致了这个问题,我需要在订阅时捕获错误。

以下是操作,实际上这是一个非常基本的内容,它只是通过电子邮件地址从Web服务加载配置文件的流程。

这是三个动作:

export enum ActionTypes {
  Begin = "[Profile] Load data begin",
    Success = "[Profile] Load data success",
    Failure = "[Profile] Load data failure"
}

export class LoadProfileBegin implements Action {
  readonly type = ActionTypes.Begin;
  constructor(public email: string) {}
}

/**
 * The main thing to note here is that our LoadDataSuccess and 
 * LoadDataFailure actions will include a payload - we will either 
 * pass the loaded data along with LoadDataSuccess or we will 
 * pass the error to LoadDataFailure.
 */
export class LoadProfileSuccess implements Action {
  readonly type = ActionTypes.Success;

  constructor(public payload: {
    data: any
  }) { }
}

export class LoadProfileFailure implements Action {
  readonly type = ActionTypes.Failure;

  constructor(public payload: {
    error: any
  }) { }
}

export type ActionsUnion = LoadProfileBegin | LoadProfileSuccess | LoadProfileFailure;

然后我有一个服务来调用休息服务,该服务将返回一个Observable效果:

  public loadByEmail(email: string, showLoading ? : boolean): Observable < any > {
    const data: any = {
      'email': email
    };
    return <Observable < any >> this.restService.sendPost('profiles__/find-by-email', data);
  }

然后我有两种方法:一种调度动作,另一种返回状态:

  loadProfileState(email: string) {
    this.store.dispatch(new ProfileActions.LoadProfileBegin(email));
  }

  getProfileState(): Store < ProfileState > {
    return this.store.select(getProfileState);
  }

然后在某些组件中,我订阅尝试捕获该错误:

this.profileService.getProfileState().subscribe(state => {
  if (state.payload) {
    const profile = state.payload.json;
    this.setProfileData(profile, true);
  } 

  if (state.error){
    // This one here never reaches
  }
});

您可以在下面的图片中看到,该错误发生了,但从未使用该操作捕获并传递: enter image description here

我知道很多,但是如果有人能注意到任何事情并将其指向我,我将非常感激。

1 个答案:

答案 0 :(得分:1)

我怀疑当您的效果“ catchError”运算符返回of(....)时,正在调用您的reducer。实际上,您必须返回-

之类的操作。
@Effect() loadByEmail = this.actions
    .pipe(
      ofType(ProfileActions.ActionTypes.Begin),
      map((action: ProfileActions.LoadProfileBegin) => action),
      switchMap(action => this.service.loadByEmail(action.email, true)),
      map(response => ({
        type: ProfileActions.ActionTypes.Success,
        payload: response,
        error: null
      })),
      catchError((error) => [new ProfileActions.LoadProfileFailure({error})])
    );