Reputation: 828
Could someone help me to see what's wrong here that every time I try to cause an error I get:
core.js:12632 ERROR TypeError: Cannot read property 'error' of undefined
My Effect:
@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
}))
);
The reducer:
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;
I think I might be doing some big mistake here that causes this problem, I need to capture the error when subscribing.
Here are the actions, actually it's a very basic stuff, it's just a flow to load a profile from the web service by an email address.
Here are the three actions:
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;
Then I have a service to call a rest service which will return an Observable to the Effect:
public loadByEmail(email: string, showLoading ? : boolean): Observable < any > {
const data: any = {
'email': email
};
return <Observable < any >> this.restService.sendPost('profiles__/find-by-email', data);
}
Then I have two methods: one to dispatch the action and the other to return the state:
loadProfileState(email: string) {
this.store.dispatch(new ProfileActions.LoadProfileBegin(email));
}
getProfileState(): Store < ProfileState > {
return this.store.select(getProfileState);
}
And then in some component I subscribe trying to catch the error:
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
}
});
As you can see on the image below the error happens but never capture and passed using the action:
I know it's a lot but if someone could notice anything and point it to me I would appreciate very much.
Upvotes: 0
Views: 158
Reputation: 5602
I doubt that your reducer is being called when your effect "catchError" operator returns of(....). In fact, you must return an action like -
@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})])
);
Upvotes: 1