diff --git a/packages/form-core/src/FieldApi.ts b/packages/form-core/src/FieldApi.ts index 0bf59f58f..aee79be7a 100644 --- a/packages/form-core/src/FieldApi.ts +++ b/packages/form-core/src/FieldApi.ts @@ -1103,6 +1103,19 @@ export class FieldApi< this.update(this.options as never) const { onMount } = this.options.validators || {} + const formFieldMeta = this.form.getFieldMeta(this.name) + console.log(this.name) + console.log(formFieldMeta) + + if (formFieldMeta && formFieldMeta.errors.length > 0) { + this.setMeta((prev) => ({ + ...prev, + + errorMap: formFieldMeta.errorMap, + errorSourceMap: formFieldMeta.errorSourceMap, + errors: formFieldMeta.errors, + })) + } if (onMount) { const error = this.runValidator({ diff --git a/packages/form-core/src/FormApi.ts b/packages/form-core/src/FormApi.ts index 1dfb98e97..84e0eb2cd 100644 --- a/packages/form-core/src/FormApi.ts +++ b/packages/form-core/src/FormApi.ts @@ -1981,6 +1981,7 @@ export class FormApi< (prev) => [...(Array.isArray(prev) ? prev : []), value] as any, opts, ) + this.validateField(field, 'change') } diff --git a/packages/form-core/tests/FieldApi.spec.ts b/packages/form-core/tests/FieldApi.spec.ts index 1935e19d4..95479e22c 100644 --- a/packages/form-core/tests/FieldApi.spec.ts +++ b/packages/form-core/tests/FieldApi.spec.ts @@ -2500,4 +2500,72 @@ describe('field api', () => { expect(field.state.meta.errors).toStrictEqual(['Blur error']) }) + + it('should pass errors to pushed fields', () => { + const schema = z.object({ arr: z.array(z.string().min(2)) }) + + const form = new FormApi({ + defaultValues: { + arr: [''], + }, + validators: { onChange: schema }, + }) + form.mount() + + const field = new FieldApi({ + form, + name: 'arr', + }) + field.mount() + field.pushValue('') + + expect(form.state.errors).toStrictEqual([ + { + 'arr[0]': [ + { + code: 'too_small', + exact: false, + inclusive: true, + message: 'String must contain at least 2 character(s)', + minimum: 2, + path: ['arr', 0], + type: 'string', + }, + ], + 'arr[1]': [ + { + code: 'too_small', + exact: false, + inclusive: true, + message: 'String must contain at least 2 character(s)', + minimum: 2, + path: ['arr', 1], + type: 'string', + }, + ], + }, + ]) + + const fieldIndexed = new FieldApi({ + form, + name: 'arr[1]', + }) + fieldIndexed.mount() + + expect(form.getFieldMeta(fieldIndexed.name)).toEqual([]) + + expect(fieldIndexed.state.meta.errors).toStrictEqual({ + errors: [ + { + code: 'too_small', + minimum: 2, + type: 'string', + inclusive: true, + exact: false, + message: 'String must contain at least 2 character(s)', + path: ['arr', 1], + }, + ], + }) + }) }) diff --git a/packages/react-form/src/useForm.tsx b/packages/react-form/src/useForm.tsx index ce3c8ecd5..a65afc500 100644 --- a/packages/react-form/src/useForm.tsx +++ b/packages/react-form/src/useForm.tsx @@ -6,13 +6,12 @@ import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect' import type { AnyFormApi, AnyFormState, - BaseFormOptions, FormAsyncValidateOrFn, FormOptions, FormState, FormValidateOrFn, } from '@tanstack/form-core' -import type { ComponentType, JSX, PropsWithChildren, ReactNode } from 'react' +import type { PropsWithChildren, ReactNode } from 'react' import type { FieldComponent } from './useField' import type { NoInfer } from '@tanstack/react-store'