Have you ever had trouble validating something from a 3rd party library, using Zod? Like a date. Let's take a look.
Zod is great! Front-end validation using Zod is very helpful and easy as long as you stick to the docs and built-in types. When using non-Zod-native data types in your schema, however, you might get into a bit of a pickle. Just like I did in my first serious Next.js project. Here I want to share how I managed to validate a Moment.js date object from a date picker component inside a submission form. Because I couldn't find a solution online.
TL;DR
If you are looking for a quick solution, see above. That's it.
For a little story and explanation, read on.
A little background
Imagine you are building a movie/book/concert/event listings/calendar type of thing. And you let your users submit new entries in your app. You are building this in React with Typescript. You also do not want to build everything from scratch.
That is my recent project where users can submit new entries with data, such as title
, description
, start_date
, entry_price
etc. etc. Focusing on the start_date
field, I also chose to use a fancy pre-built date-time picker component. Users can easily pick a date and also a time when the event is happening. This is the react-datetime component which requires moment.js to work.
Now, if I was working with native JS Date objects, validation would have been straightforward. Zod knows what to do. But the date picker returns its output value as a Moment date object. And this is how I made it work in Zod.
Breakdown
Let's look at a real use-case example and break down the process.
- import the main zod object
z
- import the main
moment
object and a utility functionisMoment
which simply returns a boolean and requires a date as its argument - import the Typescript declaration of the
Moment
date object - create a Zod schema declaration using the
custom
type declaration, provide the validation rule and finally transform the validated data - Run the validation by passing a Moment.js object into Zod's
parse
method
Let's get into points #4 and #5 for all the details
#4: Building the schema
Not too long ago, Zod added the option to pass in custom types into its schema builder work-flow. We are using this feature and providing it with the Moment
type, that comes in the moment.js
library.
Next, I am providing a validation check as an arrow function, which simply takes the value that comes in to be checked, and passes it to the isMoment
utility function, also shipped with moment.js
. This returns true/false
based on what is passed in. Below is an example of a Moment.js date object as it comes in from the form.
If the check fails, I am providing an optional error message to be sent back from validation.
After validation is successful, I am passing the result into Zod's transform
function, where the validated value
is being formatted into an ISO 8601 string, using moment().format()
(check the moment docs for details). Just because my API requires it like that.
#5: Parsing the input
Every Zod schema instance has available the parse
method, which is essentially the one doing the validation. When you pass data into it and the data matches its schema, the method returns the value. If it does not match the schema, an error is thrown.
Conclusion
And that's it! I hope this will be helpful and someone can avoid the troubles I went through. Building custom validation schemas with Zod is not too difficult, it only requires some creativity. By using type declarations which are shipped with the 3rd party library and a clever validation check (this could have been written manually as well, but why bother), Zod continues to help with on demand validation and keeps your form in top-shape.
Last but not least
Zod is awesome! Simple as that. Automatic and highly complex front-end validation is made easy with this great library. And, of course, Zod is Typescript-first. Make sure to check it out when building your next thing. Shout out to Colin for his great work. (This is not sponsored, it's just a great tool).
Top comments (0)