I am trying to remove an item from the redux store. When I delete the item from the UI, I get the error "cannot read property CourseId of undefined". The error is coming from the DELETE_COURSE_SUCCESS action of the reducer when I try to use filter to remove the item.
Here is my API
static deleteCourse(course) {
if (course.CourseId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
let url = '/api/courses/delete/' + course.CourseId;
fetch(url, {
method: 'post',
dataType: 'json',
credentials: 'include',
contentType: "application/json",
headers : {
'Accept':'application/json',
'Content-Type': 'application/json'
}
}).then((response) => {
if (response.ok === true)
return response;
}).catch(function(err) {
alert('Error: ' + err);
});
resolve(course);
}, delay);
});
}
}
And my Action:
export function deleteCourseSuccess(course) {
return { type: types.DELETE_COURSE_SUCCESS, course };
}
export function deleteCourse(course) {
return function(courseDispatch, getState) {
courseDispatch(beginAjaxCall());
return courseApi.deleteCourse(course).then(deletedCourse => {
courseDispatch(deleteCourseSuccess(deletedCourse));
}).catch(error => {
courseDispatch(ajaxCallError(error));
throw(error);
});
};
}
Here is my Reducer:
export default function courseReducer(state = initialState.courses, action) {
switch(action.type) {
case types.LOAD_COURSES_SUCCESS:
return action.courses;
case types.CREATE_COURSE_SUCCESS:
return [
...state,
Object.assign({}, action.course)
];
case types.UPDATE_COURSE_SUCCESS:
return [
...state.filter(course => course.CourseId !== action.course.CourseId),
Object.assign({}, action.course)
];
case types.DELETE_COURSE_SUCCESS:
return [
// this is where the error occurs, says that course is undefined
...state.filter(course => course.CourseId !== action.course.CourseId)
];
default:
return state;
}
}
Here is the delete method in the component:
deleteCourse(event) {
event.preventDefault();
this.setState({deleting: true});
this.props.actions.deleteCourse(this.state.course)
.then(() => this.redirect())
.catch(error => {
toastr.error('deleteCourse:' + error);
this.setState({deleting: false});
});
}
If I just return ...state in the DELETE_COURSE_SUCCESS action type, I don't get the error but the deleted item is still in the state. I know the item is in there too because I put the following alert before the return statement and saw it in there:
alert(JSON.stringify(state.filter(course => course.CourseId === action.course.CourseId)));
It is probably something simple I am missing but for the life of me I can't figure it out.
Edit: I found the culprit. In the component from where I am deleting the item, I have the following:
componentWillReceiveProps(nextProps) {
if (this.props.course.CourseId != nextProps.course.CourseId) {
// necessary to populate form when existing course is loaded directly
this.setState({course: Object.assign({}, nextProps.course)});
}
}
When I commented this out, the error went away. It was "nextProps.course" that was undefined. Guess I better read up on react component lifecycles a little more instead of just blindly copying and pasting code :(