Zod Async Refine always returning false
nosizejosh opened this issue ยท comments
Environment
- Operating System: Windows_NT
- Node Version: v20.11.1
- Nuxt Version: 3.11.2
- CLI Version: 3.11.1
- Nitro Version: 2.9.6
- Package Manager: npm@10.4.0
- Builder: -
- User Config: ssr, debug, runtimeConfig, devtools, modules, ui, css, app, supabase, security
- Runtime Modules: @nuxtjs/supabase@1.2.0, @vueuse/nuxt@10.9.0, @pinia/nuxt@0.5.1, @nuxt/ui@2.15.2, @pinia-plugin-persistedstate/nuxt@1.2.0, nuxt-icon@0.6.10, @nuxtjs/device@3.1.1
- Build Modules: -
Reproduction
// discussion link #27331
Describe the bug
Hello,
I am trying to validate a form with an async request to a server route that works fine when tested on its own, however, in the zod validation always returns false.
I am trying to prevent user from attempting to register with an email that has already been taken, and so validating inside a nuxtui form by calling this async server route.
testing the server route works just fine and return expected true or false
http://localhost:3000/user/is_email_available?email=er.ttt@gmail.com
returns true or false as expected
but for some reason always returns false in the zod schema validation.
const schema = z.object({
tenant_name: z.string({ required_error: "Business Name is required" }).
min(2, { message: "Must be at least 2 characters" }).
refine(async (val) => await tenantSlugAvailable(slugify(val)), (val) => ({ message: `${val} is not available` })),
email: z.string({ required_error: "Business Email is required" }).email({ message: "Invalid email address" }).
refine(async (val) => { await useFetch('user/is_email_available', { query: { email: val } }) }, (val) => ({ message: `${val} is not available` })),
password: z.string({ required_error: "Password is required" }).min(8, { message: 'Must be at least 8 characters' }),
confirmPassword: z.string({ required_error: "Password Confirmation is required" }).min(8, { message: 'Must be at least 8 characters' })
}).refine((values) => values.password === values.confirmPassword,
{
message: "Passwords must match!",
path: ["confirmPassword"],
}
);
Please can someone take a look and show me what I am doing wrong? have spent a day on this already and not making any headway.
Thanks
Additional context
Logs
No response
Would you be able to provide a reproduction? ๐
More info
Why do I need to provide a reproduction?
Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making.
What will happen?
If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritize it based on its severity and how many people we think it might affect.
If needs reproduction
labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it.
How can I create a reproduction?
We have a couple of templates for starting with a minimal reproduction:
๐ https://stackblitz.com/github/nuxt/starter/tree/v3-stackblitz
๐ https://codesandbox.io/s/github/nuxt/starter/v3-codesandbox
A public GitHub repository is also perfect. ๐
Please ensure that the reproduction is as minimal as possible. See more details in our guide.
You might also find these other articles interesting and/or helpful:
This seems like a zod question rather than a Nuxt one.
@danielroe yes I have asked in zod as well. Asking here in case someone has faced and resolved a similar challenge.
I have checked the documentation and the only thing that maybe accounting for this will be
this warning from the docs โ ๏ธ If you use async refinements, you must use the .parseAsync method to parse data! Otherwise Zod will throw an error.
but I have other methods that are also async and work just fine ( they don't call server api methods but superbase api via client)
resolved with the help of @Boluwatife2904.
Issue was with returning a value from the usefetch call.
email: z.string({ required_error: "Business Email is required" }).email({ message: "Invalid email address" }). refine(async (val) => { const { data, error } = await useFetch('/user/is_email_available', { query: { email: val } }); return data.value }, (val) => ({ message:
${val} is not available })),