logaretm / vee-validate

✅ Painless Vue forms
https://vee-validate.logaretm.com/v4
MIT License
10.79k stars 1.26k forks source link

Issue with Schema Mutation Using `.transform()` in conjunction with `initialValues` from `useForm()` #4638

Open RazorSiM opened 9 months ago

RazorSiM commented 9 months ago

What happened?

I'm encountering an issue with the .transform() method in schemas and initialValues when dealing with differing input and output schemas.

To illustrate, consider the following schema:

const schema = z.object({
  foo: z.string(),
  bar: z.string(),
  zoo: z.string(),
}).transform((data) => {
  return {
    pluto: data.foo + data.bar + data.zoo,
  }
})

The problem arises when initializing the form with initial values for all fields. The schema is altered, adding pluto as a new field in the form: image image

Despite re-entering the values, this issue persists: image image

This makes the validation fail.

Currently, my workaround involves using two separate schemas: one standard and one transformed with .transform(). Before submitting data, I parse the values using the transformed schema.

Based on my observations in the developer tools, this behavior doesn't seem intentional.

For a demonstration of this issue, please visit: https://stackblitz.com/edit/vitejs-vite-r9mxtn?file=src%2FApp.vue

Reproduction steps

  1. define a schema and apply the .transform() function, returning a new field pluto
  2. set the initialValues for foo, bar, zoo
  3. check the vee-validate debug tools

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

Relevant log output

No response

Demo link

https://stackblitz.com/edit/vitejs-vite-r9mxtn?file=src%2FApp.vue

Code of Conduct

RazorSiM commented 9 months ago

To add on this: resetForm() is affected too!

RazorSiM commented 8 months ago

Going through the code, it seems like this behavior cannot be "fixed". Zod always applies the transformations when parsing, if the object structure changes, then the bug appears.

The solution in my case is to have a separate schema with the transform and apply the parse before sending the data to the endpoint.

logaretm commented 8 months ago

You are right, parsing will occur only at initialization or submission, I considered going all the way with this by re-parsing the schema everytime validation occurs but it is not reliable and transformations may result in fields being mismatched with their paths.

So a separate parsedValues may sound like a viable approach here, marking this as an enhancement.

RazorSiM commented 8 months ago

You are right, parsing will occur only at initialization or submission, I considered going all the way with this by re-parsing the schema everytime validation occurs but it is not reliable and transformations may result in fields being mismatched with their paths.

So a separate parsedValues may sound like a viable approach here, marking this as an enhancement.

What about adding an optional parameter to the toTypedSchema() that accepts a zod .transform() function as a callback, and use it within the handleSubmit?

A separate parsedValues returned from the useForm() composable would be great too!