Может ли кто-нибудь помочь мне понять, что здесь не так, что каждый раз, когда я пытаюсь вызвать ошибку, я получаю:
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;
Я думаю, что, возможно, я делаю здесь большую ошибку, которая вызывает эту проблему, мне нужно зафиксировать ошибку при подписке.
Вот действия, на самом деле это очень простые вещи, это просто процесс загрузки профиля из веб-сервиса по адресу электронной почты.
Вот три действия:
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
}
});
Как вы можете видеть на изображении ниже, ошибка возникает, но никогда не захватывается и не передается с помощью действия:
Я знаю, что это много, но если кто-то может что-нибудь заметить и указать на это мне, я был бы очень признателен.
Я сомневаюсь, что ваш редуктор вызывается, когда ваш эффект "catchError" возвращает оператор (....). Фактически, вы должны вернуть такое действие, как -
@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})])
);