I am trying to make an input that should take in a number between a certain range. When I submit it, zod says it expected a number but got a string.
import {z} from "zod"
import { fromZodError } from "zod-validation-error";
//give this file it's own unique name to identify the form it uses
export const creditCardData = z.object({
//------name------
firstName: z.string().min(3, 'Min Length must be 3').max(10, 'Max Length must be 10'),
age: z.number().min(1).max(99).int()
})
export const defaultCardData={
firstName:'',
age: 0
}
export type CardData = z.infer<typeof creditCardData>
//form submit function
export const handleSubmit = (
event: React.FormEvent<HTMLFormElement>,
submission: CardData,
isError: (val: boolean) => void,
isLoading: (val: boolean) => void
) => {
event.preventDefault();
isLoading(true)
const results = creditCardData.safeParse(submission);
if (!results.success) {
const errorType = fromZodError(results.error);
console.log(errorType.message);
isLoading(false)
isError(true)
} else {
isError(false)
isLoading(false)
//put api call
console.log(results.data);
}
};
Here is my zod file where I do my validation
import { useState } from "react";
import { CardData, defaultCardData, handleSubmit } from "./validation/zod";
import Input from "./components/Input";
function App() {
//state date for form
const [data, setData] = useState<CardData>(defaultCardData);
//loading and function
const [loading, setLoading] = useState(false);
const isLoading = (val: boolean) => setLoading(val);
//error and function
const [error, setError] = useState(false);
const isError = (val: boolean) => setError(val);
return (
<main className="min-h-screen flex justify-center flex-col items-center text-white">
<h1 className="text-2xl font-bold ">Card Data</h1>
<form
className="text-black"
onSubmit={(event) => handleSubmit(event, data, isError, isLoading)}
>
{/* //first name */}
<Input
label="First Name "
id="firstName"
value={data.firstName}
handleChange={(e: { target: { value: string } }) => {
setData({ ...data, firstName: e.target.value });
}}
/>
{/* //age */}
<Input
label="Age "
id="age"
value={data.age}
type="number"
handleChange={(e: { target: { value: number } }) => {
setData({ ...data, age: e.target.value });
}}
/>
{/* //submit */}
<button
className="block mt-4 p-2 bg-white border-black border-2 rounded-md"
type="submit"
>
Submit
</button>
{loading && <p>Loading...</p>}
{error && <p>Error on submission</p>}
</form>
</main>
);
}
export default App;
and here is the part where I have the user input. When I submit I get the error "Validation error: Expected number, received string at "age". "
As per the Zod documentation, Zod now provides a more convenient way to coerce primitive values.
age: z.coerce.number().gte(18, 'Must be 18 and above');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With