在 Ionic 3 的 NgRx 中传递错误 URL 时,Reducer 错误始终未定义
Reducer error always undefined when passing wrong URL in NgRx in Ionic 3
谁能帮我看看这里出了什么问题,每次我尝试导致错误时,我都会得到:
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;
然后我有一个调用休息服务的服务,它将 return 一个可观察到的效果:
public loadByEmail(email: string, showLoading ? : boolean): Observable < any > {
const data: any = {
'email': email
};
return <Observable < any >> this.restService.sendPost('profiles__/find-by-email', data);
}
然后我有两种方法:一种是分派动作,另一种是 return 状态:
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
}
});
正如您在下图中看到的,错误发生但从未使用操作捕获和传递:
我知道很多,但如果有人能注意到任何东西并指给我看,我将不胜感激。
我怀疑当你的 effect "catchError" operator returns of(....) 时你的 reducer 被调用了。事实上,您必须 return 像这样的操作 -
@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})])
);
谁能帮我看看这里出了什么问题,每次我尝试导致错误时,我都会得到:
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;
然后我有一个调用休息服务的服务,它将 return 一个可观察到的效果:
public loadByEmail(email: string, showLoading ? : boolean): Observable < any > {
const data: any = {
'email': email
};
return <Observable < any >> this.restService.sendPost('profiles__/find-by-email', data);
}
然后我有两种方法:一种是分派动作,另一种是 return 状态:
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
}
});
正如您在下图中看到的,错误发生但从未使用操作捕获和传递:
我知道很多,但如果有人能注意到任何东西并指给我看,我将不胜感激。
我怀疑当你的 effect "catchError" operator returns of(....) 时你的 reducer 被调用了。事实上,您必须 return 像这样的操作 -
@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})])
);