delete item from store redux

1k views Asked by At

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 :(

0

There are 0 answers