Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/form-core/src/FormApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2659,13 +2659,12 @@ export class FormApi<

batch(() => {
if (!dontUpdateMeta) {
this.setFieldMeta(field, (prev) => ({
this.setFieldMeta(field, (prev = defaultFieldMeta) => ({
...prev,
isTouched: true,
isDirty: true,
errorMap: {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
...prev?.errorMap,
...prev.errorMap,
onMount: undefined,
},
}))
Expand Down
30 changes: 30 additions & 0 deletions packages/form-core/tests/FormApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,36 @@ describe('form api', () => {
})
})

it('should create complete meta when setFieldValue targets an uninitialized field', () => {
const form = new FormApi({
defaultValues: {
availableFor: 'longStay',
} as { availableFor: string; fees?: number },
})
form.mount()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Clean up the form mount in the test.

form.mount() registers listeners and returns a cleanup function. Capture and invoke it in finally to prevent cross-test listener leaks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/form-core/tests/FormApi.spec.ts` at line 92, Update the test around
form.mount() to capture its returned cleanup function and invoke that cleanup in
a finally block, ensuring listeners are removed even when the test fails.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the touched/dirty assertions from the review summary in 51d4103 (verified the runtime values by running the test). On the mount cleanup: skipping this one — the suite has ~136 form.mount() calls and none capture the cleanup, and the event-client listeners are keyed by each form's unique _formId, so there's no cross-test interference. Making just this test different from the rest of the file felt inconsistent; happy to do a suite-wide cleanup pass in a separate PR if maintainers want it.


// `fees` is rendered conditionally and has not been mounted yet, so its
// meta is created for the first time by this call.
form.setFieldValue('fees', 1)

const meta = form.getFieldMeta('fees')

// Every documented meta field must be present (not `undefined`), matching
// the meta of a field that has been mounted normally.
expect(meta).toMatchObject({
isValidating: false,
isBlurred: false,
// `setFieldValue` marks the newly created meta as touched and dirty.
isTouched: true,
isDirty: true,
errors: [],
errorSourceMap: {},
})
expect(meta?.isValidating).not.toBeUndefined()
expect(meta?.isBlurred).not.toBeUndefined()
expect(meta?.errorSourceMap).not.toBeUndefined()
})

it('should reset with provided custom default values', () => {
const defaultValues = {
name: 'test',
Expand Down