Skip to content

Commit b2db36a

Browse files
juanvilladevautofix-ci[bot]crutchcorn
authored
fix(form-core): clear previous invalid sync validation errors on FormApi (#1157)
* fix(form-core): clear previous sync validation errors on FormApi when no longer valid When performing sync validation, ensure that previous field errors are cleared if they are no longer present in the new validation result. This prevents stale validation errors from persisting in the form state. * ci: apply automated fixes and generate docs accept incoming changes * fix(form-core): clear previous stale sync validation errors using new FormErrorMapFromValidator type * fix(form-core): batch updates to baseStore in validateSync * ci: apply automated fixes and generate docs * ci: apply automated fixes and generate docs --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Corbin Crutchley <[email protected]>
1 parent 738faf2 commit b2db36a

File tree

3 files changed

+139
-48
lines changed

3 files changed

+139
-48
lines changed

docs/reference/classes/formapi.md

+24-24
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ However, if you need to create a new instance manually, you can do so by calling
4545
new FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>(opts?): FormApi<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>
4646
```
4747
48-
Defined in: [packages/form-core/src/FormApi.ts:721](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L721)
48+
Defined in: [packages/form-core/src/FormApi.ts:735](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L735)
4949
5050
Constructs a new `FormApi` instance with the given form options.
5151
@@ -137,7 +137,7 @@ Defined in: [packages/form-core/src/FormApi.ts:709](https://github.com/TanStack/
137137
deleteField<TField>(field): void
138138
```
139139
140-
Defined in: [packages/form-core/src/FormApi.ts:1701](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1701)
140+
Defined in: [packages/form-core/src/FormApi.ts:1734](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1734)
141141
142142
#### Type Parameters
143143
@@ -161,7 +161,7 @@ Defined in: [packages/form-core/src/FormApi.ts:1701](https://github.com/TanStack
161161
getAllErrors(): object
162162
```
163163
164-
Defined in: [packages/form-core/src/FormApi.ts:1912](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1912)
164+
Defined in: [packages/form-core/src/FormApi.ts:1945](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1945)
165165
166166
Returns form and field level errors
167167
@@ -212,7 +212,7 @@ errors: (
212212
getFieldInfo<TField>(field): FieldInfo<TFormData>
213213
```
214214
215-
Defined in: [packages/form-core/src/FormApi.ts:1610](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1610)
215+
Defined in: [packages/form-core/src/FormApi.ts:1643](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1643)
216216
217217
Gets the field info of the specified field.
218218
@@ -238,7 +238,7 @@ Gets the field info of the specified field.
238238
getFieldMeta<TField>(field): undefined | AnyFieldMeta
239239
```
240240
241-
Defined in: [packages/form-core/src/FormApi.ts:1601](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1601)
241+
Defined in: [packages/form-core/src/FormApi.ts:1634](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1634)
242242
243243
Gets the metadata of the specified field.
244244
@@ -264,7 +264,7 @@ Gets the metadata of the specified field.
264264
getFieldValue<TField>(field): DeepValue<TFormData, TField>
265265
```
266266
267-
Defined in: [packages/form-core/src/FormApi.ts:1594](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1594)
267+
Defined in: [packages/form-core/src/FormApi.ts:1627](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1627)
268268
269269
Gets the value of the specified field.
270270
@@ -292,7 +292,7 @@ Gets the value of the specified field.
292292
handleSubmit(): Promise<void>
293293
```
294294
295-
Defined in: [packages/form-core/src/FormApi.ts:1519](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1519)
295+
Defined in: [packages/form-core/src/FormApi.ts:1552](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1552)
296296
297297
Handles the form submission, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.
298298
@@ -306,7 +306,7 @@ Handles the form submission, performs validation, and calls the appropriate onSu
306306
handleSubmit(submitMeta): Promise<void>
307307
```
308308
309-
Defined in: [packages/form-core/src/FormApi.ts:1520](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1520)
309+
Defined in: [packages/form-core/src/FormApi.ts:1553](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1553)
310310
311311
Handles the form submission, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.
312312
@@ -332,7 +332,7 @@ insertFieldValue<TField>(
332332
opts?): Promise<void>
333333
```
334334
335-
Defined in: [packages/form-core/src/FormApi.ts:1730](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1730)
335+
Defined in: [packages/form-core/src/FormApi.ts:1763](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1763)
336336
337337
#### Type Parameters
338338
@@ -368,7 +368,7 @@ Defined in: [packages/form-core/src/FormApi.ts:1730](https://github.com/TanStack
368368
mount(): () => void
369369
```
370370
371-
Defined in: [packages/form-core/src/FormApi.ts:1022](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1022)
371+
Defined in: [packages/form-core/src/FormApi.ts:1036](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1036)
372372
373373
#### Returns
374374
@@ -390,7 +390,7 @@ moveFieldValues<TField>(
390390
opts?): void
391391
```
392392
393-
Defined in: [packages/form-core/src/FormApi.ts:1859](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1859)
393+
Defined in: [packages/form-core/src/FormApi.ts:1892](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1892)
394394
395395
Moves the value at the first specified index to the second specified index within an array field.
396396
@@ -431,7 +431,7 @@ pushFieldValue<TField>(
431431
opts?): void
432432
```
433433
434-
Defined in: [packages/form-core/src/FormApi.ts:1715](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1715)
434+
Defined in: [packages/form-core/src/FormApi.ts:1748](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1748)
435435
436436
Pushes a value into an array field.
437437
@@ -468,7 +468,7 @@ removeFieldValue<TField>(
468468
opts?): Promise<void>
469469
```
470470
471-
Defined in: [packages/form-core/src/FormApi.ts:1788](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1788)
471+
Defined in: [packages/form-core/src/FormApi.ts:1821](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1821)
472472
473473
Removes a value from an array field at the specified index.
474474
@@ -506,7 +506,7 @@ replaceFieldValue<TField>(
506506
opts?): Promise<void>
507507
```
508508
509-
Defined in: [packages/form-core/src/FormApi.ts:1762](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1762)
509+
Defined in: [packages/form-core/src/FormApi.ts:1795](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1795)
510510
511511
Replaces a value into an array field at the specified index.
512512
@@ -544,7 +544,7 @@ Replaces a value into an array field at the specified index.
544544
reset(values?, opts?): void
545545
```
546546
547-
Defined in: [packages/form-core/src/FormApi.ts:1098](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1098)
547+
Defined in: [packages/form-core/src/FormApi.ts:1112](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1112)
548548
549549
Resets the form state to the default values.
550550
If values are provided, the form will be reset to those values instead and the default values will be updated.
@@ -577,7 +577,7 @@ Optional options to control the reset behavior.
577577
resetFieldMeta<TField>(fieldMeta): Record<TField, AnyFieldMeta>
578578
```
579579
580-
Defined in: [packages/form-core/src/FormApi.ts:1647](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1647)
580+
Defined in: [packages/form-core/src/FormApi.ts:1680](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1680)
581581
582582
#### Type Parameters
583583
@@ -601,7 +601,7 @@ Defined in: [packages/form-core/src/FormApi.ts:1647](https://github.com/TanStack
601601
setErrorMap(errorMap): void
602602
```
603603
604-
Defined in: [packages/form-core/src/FormApi.ts:1886](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1886)
604+
Defined in: [packages/form-core/src/FormApi.ts:1919](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1919)
605605
606606
Updates the form's errorMap
607607
@@ -623,7 +623,7 @@ Updates the form's errorMap
623623
setFieldMeta<TField>(field, updater): void
624624
```
625625
626-
Defined in: [packages/form-core/src/FormApi.ts:1629](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1629)
626+
Defined in: [packages/form-core/src/FormApi.ts:1662](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1662)
627627
628628
Updates the metadata of the specified field.
629629
@@ -656,7 +656,7 @@ setFieldValue<TField>(
656656
opts?): void
657657
```
658658
659-
Defined in: [packages/form-core/src/FormApi.ts:1671](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1671)
659+
Defined in: [packages/form-core/src/FormApi.ts:1704](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1704)
660660
661661
Sets the value of the specified field and optionally updates the touched state.
662662
@@ -694,7 +694,7 @@ swapFieldValues<TField>(
694694
opts?): void
695695
```
696696
697-
Defined in: [packages/form-core/src/FormApi.ts:1830](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1830)
697+
Defined in: [packages/form-core/src/FormApi.ts:1863](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1863)
698698
699699
Swaps the values at the specified indices within an array field.
700700
@@ -732,7 +732,7 @@ Swaps the values at the specified indices within an array field.
732732
update(options?): void
733733
```
734734
735-
Defined in: [packages/form-core/src/FormApi.ts:1039](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1039)
735+
Defined in: [packages/form-core/src/FormApi.ts:1053](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1053)
736736
737737
Updates the form options and form state.
738738
@@ -754,7 +754,7 @@ Updates the form options and form state.
754754
validateAllFields(cause): Promise<unknown[]>
755755
```
756756
757-
Defined in: [packages/form-core/src/FormApi.ts:1124](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1124)
757+
Defined in: [packages/form-core/src/FormApi.ts:1138](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1138)
758758
759759
Validates all fields using the correct handlers for a given validation cause.
760760
@@ -779,7 +779,7 @@ validateArrayFieldsStartingFrom<TField>(
779779
cause): Promise<unknown[]>
780780
```
781781
782-
Defined in: [packages/form-core/src/FormApi.ts:1154](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1154)
782+
Defined in: [packages/form-core/src/FormApi.ts:1168](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1168)
783783
784784
Validates the children of a specified array in the form starting from a given index until the end using the correct handlers for a given validation type.
785785
@@ -813,7 +813,7 @@ Validates the children of a specified array in the form starting from a given in
813813
validateField<TField>(field, cause): unknown[] | Promise<unknown[]>
814814
```
815815
816-
Defined in: [packages/form-core/src/FormApi.ts:1193](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1193)
816+
Defined in: [packages/form-core/src/FormApi.ts:1207](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L1207)
817817
818818
Validates a specified field in the form using the correct handlers for a given validation type.
819819

packages/form-core/src/FormApi.ts

+57-24
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,20 @@ export class FormApi<
715715
*/
716716
prevTransformArray: unknown[] = []
717717

718+
/**
719+
* @private map of errors originated from form level validators
720+
*/
721+
prevFieldsErrorMap: FormErrorMapFromValidator<
722+
TFormData,
723+
TOnMount,
724+
TOnChange,
725+
TOnChangeAsync,
726+
TOnBlur,
727+
TOnBlurAsync,
728+
TOnSubmit,
729+
TOnSubmitAsync
730+
> = {}
731+
718732
/**
719733
* Constructs a new `FormApi` instance with the given form options.
720734
*/
@@ -899,7 +913,7 @@ export class FormApi<
899913
>
900914
>((prev, curr) => {
901915
if (curr === undefined) return prev
902-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
916+
903917
if (curr && isGlobalFormValidationError(curr)) {
904918
prev.push(curr.form as never)
905919
return prev
@@ -1229,7 +1243,7 @@ export class FormApi<
12291243
const validates = getSyncValidatorArray(cause, this.options)
12301244
let hasErrored = false as boolean
12311245

1232-
const fieldsErrorMap: FormErrorMapFromValidator<
1246+
const newFieldsErrorMap: FormErrorMapFromValidator<
12331247
TFormData,
12341248
TOnMount,
12351249
TOnChange,
@@ -1261,12 +1275,12 @@ export class FormApi<
12611275
if (fieldErrors) {
12621276
for (const [field, fieldError] of Object.entries(fieldErrors)) {
12631277
const oldErrorMap =
1264-
fieldsErrorMap[field as DeepKeys<TFormData>] || {}
1278+
newFieldsErrorMap[field as DeepKeys<TFormData>] || {}
12651279
const newErrorMap = {
12661280
...oldErrorMap,
12671281
[errorMapKey]: fieldError,
12681282
}
1269-
fieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap
1283+
newFieldsErrorMap[field as DeepKeys<TFormData>] = newErrorMap
12701284

12711285
const fieldMeta = this.getFieldMeta(field as DeepKeys<TFormData>)
12721286
if (fieldMeta && fieldMeta.errorMap[errorMapKey] !== fieldError) {
@@ -1281,6 +1295,24 @@ export class FormApi<
12811295
}
12821296
}
12831297

1298+
for (const field of Object.keys(this.prevFieldsErrorMap) as Array<
1299+
DeepKeys<TFormData>
1300+
>) {
1301+
const fieldMeta = this.getFieldMeta(field)
1302+
if (
1303+
fieldMeta?.errorMap[errorMapKey] &&
1304+
!newFieldsErrorMap[field]?.[errorMapKey]
1305+
) {
1306+
this.setFieldMeta(field, (prev) => ({
1307+
...prev,
1308+
errorMap: {
1309+
...prev.errorMap,
1310+
[errorMapKey]: undefined,
1311+
},
1312+
}))
1313+
}
1314+
}
1315+
12841316
if (this.state.errorMap[errorMapKey] !== formError) {
12851317
this.baseStore.setState((prev) => ({
12861318
...prev,
@@ -1295,28 +1327,30 @@ export class FormApi<
12951327
hasErrored = true
12961328
}
12971329
}
1330+
1331+
/**
1332+
* when we have an error for onSubmit in the state, we want
1333+
* to clear the error as soon as the user enters a valid value in the field
1334+
*/
1335+
const submitErrKey = getErrorMapKey('submit')
1336+
if (
1337+
this.state.errorMap[submitErrKey] &&
1338+
cause !== 'submit' &&
1339+
!hasErrored
1340+
) {
1341+
this.baseStore.setState((prev) => ({
1342+
...prev,
1343+
errorMap: {
1344+
...prev.errorMap,
1345+
[submitErrKey]: undefined,
1346+
},
1347+
}))
1348+
}
12981349
})
12991350

1300-
/**
1301-
* when we have an error for onSubmit in the state, we want
1302-
* to clear the error as soon as the user enters a valid value in the field
1303-
*/
1304-
const submitErrKey = getErrorMapKey('submit')
1305-
if (
1306-
this.state.errorMap[submitErrKey] &&
1307-
cause !== 'submit' &&
1308-
!hasErrored
1309-
) {
1310-
this.baseStore.setState((prev) => ({
1311-
...prev,
1312-
errorMap: {
1313-
...prev.errorMap,
1314-
[submitErrKey]: undefined,
1315-
},
1316-
}))
1317-
}
1351+
this.prevFieldsErrorMap = newFieldsErrorMap
13181352

1319-
return { hasErrored, fieldsErrorMap }
1353+
return { hasErrored, fieldsErrorMap: newFieldsErrorMap }
13201354
}
13211355

13221356
/**
@@ -1353,7 +1387,6 @@ export class FormApi<
13531387
| undefined
13541388

13551389
for (const validateObj of validates) {
1356-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
13571390
if (!validateObj.validate) continue
13581391
const key = getErrorMapKey(validateObj.cause)
13591392
const fieldValidatorMeta = this.state.validationMetaMap[key]

0 commit comments

Comments
 (0)