How to rollback redux state and database if action request failed

Viewed 68

I have a submit button will dispatch one Redux action with three axios requests. The first one is create a class, the second one is add a class teacher and the last one is add class students. The teacher table has classId foreign key which is rely on the return value of creating class. And students has foreign key of teachId referring to teacher table.

When I click the submit button, in the button onClick action, it will dispatch the Redux action. How can I handle and rollback the Redux state and database if any of the request failed?

With the frondend, my code is like

export const finalizeClassSetting = ({ className, teacherName, StudentsDetail }) => async (dispatch) => {
    dispatch({ type: CLASS_REQUEST })
    try {
        //create new class
        resultClass = createClass(className)
        dispatch({ type: CREATE_CLASS, payload: resultClass })
        const classId = resultClass.classId
        try {
            dispatch({ type: TEACHER_REQUEST })
            resultTeacher = createTeacher(teacherName,classId)
            dispatch({ type: CREATE_TEACHER, payload: resultTeacher})
            const teacherId = resultTeacher.teacherId
            try {
                dispatch({type:STUDENT_REQUEST})
                resultStudent = createStudents(classId, teacherId, studentsDetail)
                dispatch({ type: CREATE_STUDENT, payload:resultStudent })
            } catch (error) {
                dispatch({ type: STUDENT_REQUEST_FAIL, payload: error })
            }
        } catch (error) {
            dispatch({ type: TEACHER_REQUEST_FAIL, payload: error})
        }
    } catch (error) {
        dispatch({ type: CLASS_REQUEST_FAIL, payload: error})
    }
}

And createClass,createTeacher and createStudents will call the backend controller to create a new class, a new teacher and new students seperate. It's using Sequlize. It will be like

exports.createXXX = async (req, res) => {
    ...
    try {
        const resourceFound = await Model.findOne({
            where: { condition }
        })
        if (resourceFound) {
            return res.status(400).send({ status: 1, data: { message: "resource has existing" } })
        }
        const newResource = await Model.create({ xxxx })
        return res.status(200).send({ status: 0, data: { newResource: newResource, message: "create new resource successful" } })
        ...
    }
    catch(error) {
        return res.status(500).send({ status: 1, data: { message: "server error"}})
    }
}

With my current code above, if there is any error from request, the database saved to the database already cannot roll back.

0 Answers
Related