In my previous post, I described my thought process when planning to implement the delete jobs feature. In this post, I want to walk through the complete code from the front to the back of the app. I hope it helps your understanding of how React, Redux, and the back-end of your app go together – I know it will certainly help me remember this process for my next React project.
When a user clicks on the job, they see a page with all of the information about that particular job being pulled in from the API. I also created a “Delete” button on that page, which I put into its own component file. You can see here that I’ve imported the “raised button” component for styling from Material-UI, and that the component itself (written in JSX) has a label that says “Delete Job.” In the Material-UI documentation for Raised Buttons, OnMouseDown is a property on the button itself that initiates a callback function when the button is pressed. In this component, the callback is called “props.handleDelete” which we will get to see in action in the JobViewContainer where the component actually goes.
This a snippet of code for the JobViewContainer, where handleDelete is actually called. The props.handleDelete in the DeleteJobComponent from above can be seen here as a property of this container: this.handleDelete. You can also see that the ‘this’ keyword is bound to it in the constructor of the component so that it knows exactly which job is being viewed in the container.
Below the constructor, here is the actual code for handleDelete, which will be called when the delete button component from above is clicked. Basically, the dispatch function here initiates the deleteJob function inside of the Redux store, which starts the call to the database. As you can see, we send in the specific jobID as a parameter to this function so that we can correctly identify which job we want to delete from the database. The last line directs the user back to the dashboard after this function is called.
Into the Server and Back Again
This is where the deleteJob function being called in the JobViewContainer above lives. Delete job makes a DELETE request to the database using axios, a promise based HTTP client. You can see that this also dispatches other actions: dbRequest, deleteJobSuccess, and dbSuccess or dbFailure depending on the result from the call to the database. The three functions dbRequest, dbSuccess, and dbFailure are called in any function that makes a call to the database to control spinners on the page that let the user know the application is waiting for data.
When the axios call is made, the id is passed along that particular API route and onto the deleteJob method in the jobs controller where all the other methods related to job manipulation live.
The actual deleteJob method that queries the database (using the Thinky.io ORM) is below. If you’ve never seen a function like this before, it’s called a generator function and they are supported in ES6. You can tell it’s a function generator because of the asterisk (*) next to the function declaration, as well as the ‘yield’ on the fourth line. I love the concept of generator functions because they allow you take care of the asynchronous nature of calls to a database (as is the case with this particular method) in a different format. Read up on them here. Basically this function receives the id of the job the user wants to delete, and then deletes it. It also sends back to the front-end which job has been deleted so that it can be taken out of the view. Alternatively, errors are handled in the catch block in case there were any problems with access the database.
Above in the deleteJob function on the front-end, you might recall that inside of the call to axios, an action called “DELETE_JOB_SUCCESS” is dispatched inside of the reducer. Remember, a reducer takes the previous state, combines it with an action, and returns the NEW state (ie – view) of the application. In our case, it deletes any reference to the delete’s job on the user’s dashboard. This reducer is specifically taking care of all the actions that have to do with jobs – setting a user’s saved jobs on the dashboard, adding jobs, and deleting jobs. We are able to isolate the jobID from the job object that is returned from the database. “DELETE_JOB_SUCCESS” then loops through all the jobs currently in the state until it finds the one with the matching id, and then deletes it from the view.
I love using React with Redux because it helps keep your code modular and clean. In my mind, it is super clear how the user pressing the delete button sets off the chain of events that deletes all references to the job in the database and also in the view. It takes getting used to, but is great to use once it is set up!