How to validate Moment.js Date objects with Zod
Tags: zod, validation, typescript, webdev
Published: 2023-08-07 20:00:23

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

![How to validate a moment.js object in Zod](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xzhx3c1egr882zwj1qk.png)

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](https://www.npmjs.com/package/react-datetime) component which requires [moment.js](https://momentjs.com/) to work.


![Styled react-datetime picker component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8t07kehpdttw64k2hj0n.png)

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


![Extended example of Moment.js date object validation using Zod](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kygdvv95d1i9kvw85smk.png)

Let's look at a real use-case example and break down the process.

1. import the main zod object `z`
2. import the main `moment` object and a utility function `isMoment` which simply returns a boolean and requires a date as its argument
3. import the Typescript declaration of the `Moment` date object
4. create a Zod schema declaration using the `custom` type declaration, provide the validation rule and finally transform the validated data
5. 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.


![A Moment.js date object as returned from a form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tw8wbfrbdejpy1dyebg.png)


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](https://momentjs.com/docs/#/displaying/format/) 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](https://zod.dev/). Make sure to check it out when building your next thing. Shout out to [Colin ](https://colinhacks.com/) for his great work. *(This is not sponsored, it's just a great tool).*