remix-validated-form
remix-validated-form copied to clipboard
[Bug]: zod-form-data won't validate all fields at once when using safeParse
Which packages are impacted?
- [ ]
remix-validated-form
- [ ]
@remix-validated-form/with-zod
- [ ]
@remix-validated-form/with-yup
- [X]
zod-form-data
What version of these packages are you using?
"zod": "^3.22.4",
"zod-form-data": "^2.0.2"
Please provide a link to a minimal reproduction of the issue.
https://stackblitz.com/edit/vitest-dev-vitest-jswqx2?file=test%2Fbasic.test.ts
Steps to Reproduce the Bug or Issue
import { describe, expect, test } from 'vitest';
import { z } from 'zod';
import { zfd } from 'zod-form-data';
test('multiple fields should get validated at once', (v) => {
const Schema = zfd.formData(
z.object({
field1: zfd.text(),
field2: zfd.text(),
})
);
const data = new FormData();
data.append('field1', '');
data.append('field2', '');
const result = Schema.safeParse(data);
expect(result.success).toBe(false);
if (result.success) {
throw new Error('Expected failure but got success');
} else {
const errors = result.error.flatten() as z.inferFlattenedErrors<
typeof Schema
>;
// Both fields should have been validated but aren't
expect.soft(errors.fieldErrors.field1).toEqual(['Required']);
expect.soft(errors.fieldErrors.field2).toEqual(['Required']);
}
});
Expected behavior
When multiple fields are invalid, and the form data is parsed using z.safeParse
then the result object should have an error
property that contains the error information for both fields.
The actual result is that only the first field is validated. Next, when the first issue is solved by the user and resubmits the form, the error for the next field is shown.
Screenshots or Videos
No response
Platform
- OS: macOS
- Browser: arc
Additional context
No response
Thank you for the thorough reproduction! Definitely a weird bug. Interestingly, if you use safeParseAsync
instead, that fixes it (code)? Hopefully that's a reasonable workaround for now as I'm not sure when I'll have time to investigate.
I was already using the validator from withZod
as workaround which also worked.
const validator = withZod(schema);
const result = await validator.validate(data);
After your message I had a look into the source code of withZod
which seems very similar to how I was using it myself except for the use of safeParseAsync
instead of safeParse
indeed. I'll revert my code and use safeParseAsync
instead of my withZod
workaround.
I have one issue left for which I will create a separate issue.