Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): run form submit validator once on submit #1028

Merged
Merged
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
30 changes: 15 additions & 15 deletions docs/reference/classes/formapi.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ deleteField<TField>(field): void

#### Defined in

[packages/form-core/src/FormApi.ts:1117](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1117)
[packages/form-core/src/FormApi.ts:1105](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1105)

***

Expand All @@ -147,7 +147,7 @@ Gets the field info of the specified field.

#### Defined in

[packages/form-core/src/FormApi.ts:1028](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1028)
[packages/form-core/src/FormApi.ts:1016](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1016)

***

Expand All @@ -173,7 +173,7 @@ Gets the metadata of the specified field.

#### Defined in

[packages/form-core/src/FormApi.ts:1019](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1019)
[packages/form-core/src/FormApi.ts:1007](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1007)

***

Expand All @@ -199,7 +199,7 @@ Gets the value of the specified field.

#### Defined in

[packages/form-core/src/FormApi.ts:1012](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1012)
[packages/form-core/src/FormApi.ts:1000](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1000)

***

Expand Down Expand Up @@ -253,7 +253,7 @@ Inserts a value into an array field at the specified index, shifting the subsequ

#### Defined in

[packages/form-core/src/FormApi.ts:1149](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1149)
[packages/form-core/src/FormApi.ts:1137](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1137)

***

Expand Down Expand Up @@ -305,7 +305,7 @@ Moves the value at the first specified index to the second specified index withi

#### Defined in

[packages/form-core/src/FormApi.ts:1267](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1267)
[packages/form-core/src/FormApi.ts:1255](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1255)

***

Expand Down Expand Up @@ -338,7 +338,7 @@ Pushes a value into an array field.

#### Defined in

[packages/form-core/src/FormApi.ts:1131](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1131)
[packages/form-core/src/FormApi.ts:1119](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1119)

***

Expand Down Expand Up @@ -371,7 +371,7 @@ Removes a value from an array field at the specified index.

#### Defined in

[packages/form-core/src/FormApi.ts:1202](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1202)
[packages/form-core/src/FormApi.ts:1190](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1190)

***

Expand Down Expand Up @@ -407,7 +407,7 @@ Replaces a value into an array field at the specified index.

#### Defined in

[packages/form-core/src/FormApi.ts:1176](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1176)
[packages/form-core/src/FormApi.ts:1164](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1164)

***

Expand Down Expand Up @@ -462,7 +462,7 @@ resetFieldMeta<TField>(fieldMeta): Record<TField, FieldMeta>

#### Defined in

[packages/form-core/src/FormApi.ts:1062](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1062)
[packages/form-core/src/FormApi.ts:1050](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1050)

***

Expand All @@ -484,7 +484,7 @@ Updates the form's errorMap

#### Defined in

[packages/form-core/src/FormApi.ts:1291](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1291)
[packages/form-core/src/FormApi.ts:1279](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1279)

***

Expand Down Expand Up @@ -512,7 +512,7 @@ Updates the metadata of the specified field.

#### Defined in

[packages/form-core/src/FormApi.ts:1047](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1047)
[packages/form-core/src/FormApi.ts:1035](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1035)

***

Expand Down Expand Up @@ -545,7 +545,7 @@ Sets the value of the specified field and optionally updates the touched state.

#### Defined in

[packages/form-core/src/FormApi.ts:1086](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1086)
[packages/form-core/src/FormApi.ts:1074](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1074)

***

Expand Down Expand Up @@ -581,7 +581,7 @@ Swaps the values at the specified indices within an array field.

#### Defined in

[packages/form-core/src/FormApi.ts:1241](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1241)
[packages/form-core/src/FormApi.ts:1229](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1229)

***

Expand Down Expand Up @@ -613,7 +613,7 @@ Updates the form options and form state.
validateAllFields(cause): Promise<ValidationError[]>
```

Validates all fields in the form using the correct handlers for a given validation type.
Validates form and all fields in using the correct handlers for a given validation cause.

#### Parameters

Expand Down
16 changes: 2 additions & 14 deletions packages/form-core/src/FormApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ export class FormApi<
}

/**
* Validates all fields in the form using the correct handlers for a given validation type.
* Validates form and all fields in using the correct handlers for a given validation cause.
*/
validateAllFields = async (cause: ValidationCause) => {
const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any
Expand Down Expand Up @@ -967,22 +967,10 @@ export class FormApi<
this.store.setState((prev) => ({ ...prev, isSubmitting: false }))
}

// Validate all fields
// Validate form and all fields
await this.validateAllFields('submit')

// Fields are invalid, do not submit
if (!this.state.isFieldsValid) {
done()
this.options.onSubmitInvalid?.({
value: this.state.values,
formApi: this,
})
return
}

// Run validation for the form
await this.validate('submit')

if (!this.state.isValid) {
done()
this.options.onSubmitInvalid?.({
Expand Down
45 changes: 45 additions & 0 deletions packages/form-core/tests/FormApi.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,51 @@ describe('form api', () => {
])
})

it('should run form validation once during submit', async () => {
vi.useFakeTimers()
const formSubmit = vi.fn()
const fieldChangeValidator = vi
.fn()
.mockImplementation(async ({ value }) => {
await sleep(1000)
return value.length > 0 ? undefined : 'first name is required'
})

const form = new FormApi({
defaultValues: {
firstName: '',
lastName: '',
},
validators: {
onSubmitAsync: formSubmit,
},
})

const field = new FieldApi({
form,
name: 'firstName',
validators: {
onChangeAsync: fieldChangeValidator,
},
})

field.mount()
field.handleChange('test')

await vi.runAllTimersAsync()
expect(fieldChangeValidator).toHaveBeenCalledOnce()

form.handleSubmit()
await vi.runAllTimersAsync()

expect(form.state.isFieldsValid).toEqual(true)
expect(form.state.isValid).toEqual(true)
expect(form.state.canSubmit).toEqual(true)

expect(fieldChangeValidator).toHaveBeenCalledTimes(2)
expect(formSubmit).toHaveBeenCalledOnce()
})

it('should run all types of async validation on fields during submit', async () => {
vi.useFakeTimers()

Expand Down