Clean Architecture — Mapping and Displaying Server-Side Errors With Formik in React Client App

Discussing how to properly map server-side errors to individual inputs and display the errors, which complements client-side validations using Formik and Yup.

Shawn Shi
Shawn Shi
Nov 28, 2020 · 4 min read

Background

Handling server-side errors on the client-side is always tricky as it can be hard to map the errors to individual form inputs and display them accordingly. When building a React web application, using Formik and Yup allows us to handle client side errors pretty intuitively, but it is still not straightforward to handle server side errors.

In fact, there is an open issue on the Formik GitHub repo asking how to properly track and display server-side errors, in addition to client-side validation errors. While there are lots of discussions under this topic, this issue apparently is more difficult than it looks to address at the abstraction level. Even though the ticket was created in 2017, it is still open as of this writing in Nov. 2020!

The Formik author, Jared Palmer, recommends, quote to quote, “Write an small function that transforms your backend error into same shape as formik’s errors and then call setErrors”.

Goal

The goal of this article is to showcase how the recommendation from Jared can be implemented in a React web application using Formik, Yup, and TypeScript. The demo page is a form for creating a todo item.

First, let’s see how a form with just client end validation works using Formik and Yup. In the screenshot below, both Title and Category inputs are required inputs using validation schema defined using Yup. These are client end errors that nicely line up with their individual inputs.

Form to create an todo item (Screenshot by Author)

Here is the sample code used to build the form with client end errors using Formik and Yup.

Second, let’s handle generic server side error message, which does not bind to any specific form input. In the screenshot below, you will notice a red toaster with message “Error: One or more validation errors occurred.”. The message itself is from the 400 error response from the server (see console). In this case, title “test” already exists in the database and the API returned a 400 bad response with title “One or more validation errors occurred.”.

Uncommenting the following lines from the code sample above would allow us to display the generic error message in the toaster at the bottom of the screen.

Screenshot by Author
Screenshot by Author
Screenshot by Author
Screenshot by Author

Last step, how do we map the errors array from the server-side 400 response to the individual form inputs and render them accordingly? Based on Jared’s recommendation at the very beginning of this article, let’s format the server errors into the same shape as the Formik errors and set it, and Formik will know how and where to display them. In the screenshot below, notice “Title must be unique” is nicely displayed together with Title input. Lovely!

Screenshot by Author

All we had to do was to uncomment these lines in the sample code. Notice in the console, “Title” in errors is capitalized, but Formik use camel case, so we have to camel case all keys in the errors object before we ask Formik to setErrors, which in return trigger the error messages to render on the form.

Screenshot by Author

Conclusion

For best user experience and application performance, it is good practice to catch known validation errors on the client end so that they don’t hit the server. Formik plus Yup do it really well for a React application. Properly handling server side errors greatly improves the user experience as the user would know exactly what input field they need to fix, compared to only seeing a generic error “Something went wrong! Please contact site administration!”.

The sample code in this article is from a GitHub starter project. You can find the source code for the React web app part in CleanArchitectureCosmosDB.ClientApp.

This whole starter project can be used to build a React web application backed by a REST API built using ASP.NET Core and Cosmos DB. Feel free to use the whole starter project or part of it to kick start your next exciting adventure! Project Link: Clean Architecture with partitioned repository pattern using Azure Cosmos DB

Many thanks for reading! Enjoy making the world a better place with clean code!

The Startup

Medium's largest active publication, followed by +756K people. Follow to join our community.

Shawn Shi

Written by

Shawn Shi

Software Engineer, Machine Learning Engineer. When I am not dived into data and code, I am hanging out with my young daughter or outside rock climbing!

The Startup

Medium's largest active publication, followed by +756K people. Follow to join our community.

Shawn Shi

Written by

Shawn Shi

Software Engineer, Machine Learning Engineer. When I am not dived into data and code, I am hanging out with my young daughter or outside rock climbing!

The Startup

Medium's largest active publication, followed by +756K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store