Error Handling in a React/Rails Application (Active Record Validations cont…)

Luis Dejesus Castro
4 min readAug 5, 2021

--

In my previous post, I took you on a crash course into Active Record Validations. I explained its importance in regard to MVC development, and how to properly set up and implement your own validations. Now that we understand the how, we’ll talk about Errors, Error Handling, and what that looks like on the client-side.

Note: In this post, I will be focusing on React/Rails-specific capabilities. I will post another blog detailing how to set up a React/Rails application but for this post, I will assume you have a little experience developing React/Rails applications.

Errors and Validations:

In my previous example, I created a DogsController to handle the request/response flow of clients adding dogs to their personal record of dogs within my dog-walking app.

after the dog is created using the Active Record Association and dog_params, .valid? is called on the instance of dog, which runs the validations specified in your model. If no errors are found, true is returned and the dog is rendered in JSON, with a positive :created (201) status. Otherwise, the validation errors are sent to the errors hash and sent to the front-end to be displayed using dog.errors.full_messages.

In the Front-End:

For my Dog Walking app, I chose to go with a React front-end. If you are unfamiliar with React, you can find the official documentation here. React is a Javascript library for building user interfaces and it is especially useful to me because of how easy it is to create a single-page application that can asynchronously change components without the need of having to refresh the page. Since my create action is mapped to my /dogs route, I know that in order for me to send information through that route, I will need to implement a POST request.

Since this fetch request sends a form, I have called it within a handleSubmit so that the request only happens once the form is submitted. You must also use e.preventDefault to prevent the browser from performing the default action of a submit.
For my submit button, I created the styled components FormField and Button. To understand more about styled components you can find the documentation here. For organizational purposes, all of my styled-components live in a /styles folder within my /client/src folder which contains my front-end application. I have also decided to use conditional rendering to control what the user sees before and after they’ve clicked submit.

My POST request is defined within a handleSubmit, which means it will only fire off once the submit button has been clicked. In the body of my request, you can see I’ve listed all of the attribute values that I want to persist to the database. This is made possible because of Hooks.

Hooks allow developers an easy way to manipulate state without having to declare a class. It also drys allows us to write DRY code without having to manually setState.

You’ll notice that the first seven hooks handle the input fields in the form, but we also have an errors and isLoading hook. More on that in a second. Once, all your input fields are filled and the form is ready, the only thing left to do is submit your form. But right as you click submit, you realize: Oh no! you forgot to fill out the name field! This is where the errors hook comes into play.

Earlier, we discussed a POST request and why we defined it within a handleSubmit. Right after the closing parenthesis of the fetch request, we will implement something called a response handler. A response handler does exactly what its name implies: it handles the response from the backend and performs background tasks, asynchronously.

As you can see, my response handler first sets isLoading back to false, and then checks the status of the response using .ok. If the POST request passed all validations and persisted to the database, the response status will be a 201 or “created”, which means that the next line of code that gets read will be history.push(“/client-app/my-dogs”). If the request does not pass validations, the validation errors will then be sent back in a response within an errors hash and mapped into the errors hook using setErrors. Now that we know that whatever error we hit by not entering a name in the name field was sent back in the response and now exists in state via the errors hook, we can use this hook to display the error in the browser.

Once again I am using a styled component called Error to create a personalized component whose only job is to render an error when applicable. When the errors hook’s state has been changed, .map will then return a list of all the errors and render them in the browser. In my example, this looks like this:

To sum everything up, I tried submitting a form without a name, validations said NOPE, sent the errors back in a response and the front end mapped through the errors and displayed them on the page. Viola! to play around with this I emptied some of the other fields that run validations and the result was satisfying.

I hope you find this post helpful in developing your own web application.

--

--