Skip to content

Commit

Permalink
chore: change throttled validation to debounce
Browse files Browse the repository at this point in the history
  • Loading branch information
crutchcorn committed Dec 5, 2023
1 parent 1dc351e commit 9f4259f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 42 deletions.
49 changes: 25 additions & 24 deletions packages/form-core/src/FieldApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ export class FieldApi<
if (error) {
this.setMeta((prev) => ({
...prev,
errorMap: { ...prev.errorMap, onMount: error },
errorMap: { ...prev?.errorMap, onMount: error },
}))
}
}
Expand Down Expand Up @@ -514,47 +514,48 @@ export class FieldApi<
const key = getErrorMapKey(validateObj.cause)
const fieldOnChangeMeta = this.getInfo().validationMetaMap[key]

const now = Date.now()
const lastRunDiff = now - (fieldOnChangeMeta?.lastRan ?? 0)

if (fieldOnChangeMeta?.lastRan && lastRunDiff < validateObj.debounceMs) {
continue
}
fieldOnChangeMeta?.lastAbortController.abort()
// Sorry Safari 12
// eslint-disable-next-line compat/compat
const controller = new AbortController()

this.getInfo().validationMetaMap[key] = {
...fieldOnChangeMeta,
lastRan: now,
lastAbortController: controller,
}

promises.push(
new Promise<ValidationError | undefined>(async (resolve) => {
let rawError!: ValidationError | undefined
try {
rawError = await runValidatorOrAdapter({
validateFn: validateObj.validate,
value: { value, fieldApi: this, signal: controller.signal },
methodName: 'validateAsync',
adapters: [
this.form.options.validatorAdapter,
this.options.validatorAdapter as never,
],
rawError = await new Promise((resolve, reject) => {
setTimeout(() => {
if (controller.signal.aborted) return resolve(undefined)
runValidatorOrAdapter({
validateFn: validateObj.validate,
value: { value, fieldApi: this, signal: controller.signal },
methodName: 'validateAsync',
adapters: [
this.form.options.validatorAdapter,
this.options.validatorAdapter as never,
],
})
.then(resolve)
.catch(reject)
}, onChangeAsyncDebounceMs)
})
} catch (e: unknown) {
rawError = e as ValidationError
}
const error = normalizeError(rawError)
this.setMeta((prev) => ({
...prev,
errorMap: {
...prev.errorMap,
[getErrorMapKey(cause)]: error,
},
}))
this.setMeta((prev) => {
return {
...prev,
errorMap: {
...prev?.errorMap,
[getErrorMapKey(cause)]: error,
},
}
})

resolve(error)
}),
Expand Down
34 changes: 16 additions & 18 deletions packages/form-core/src/FormApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ export type FormOptions<TData, ValidatorType> = {
}

export type ValidationMeta = {
lastRan: number
lastAbortController: AbortController
}

Expand Down Expand Up @@ -421,36 +420,35 @@ export class FormApi<TFormData, ValidatorType> {
const key = getErrorMapKey(validateObj.cause)
const fieldOnChangeMeta = this.state.validationMetaMap[key]

const now = Date.now()
const lastRunDiff = now - (fieldOnChangeMeta?.lastRan ?? 0)

if (fieldOnChangeMeta?.lastRan && lastRunDiff < validateObj.debounceMs) {
continue
}
fieldOnChangeMeta?.lastAbortController.abort()
// Sorry Safari 12
// eslint-disable-next-line compat/compat
const controller = new AbortController()

this.state.validationMetaMap[key] = {
...fieldOnChangeMeta,
lastRan: now,
lastAbortController: controller,
}

promises.push(
new Promise<ValidationError | undefined>(async (resolve) => {
let rawError!: ValidationError | undefined
try {
rawError = await runValidatorOrAdapter({
validateFn: validateObj.validate,
value: {
value: this.state.values,
formApi: this,
signal: controller.signal,
},
methodName: 'validateAsync',
adapters: [this.options.validatorAdapter as never],
rawError = await new Promise((resolve, reject) => {
setTimeout(() => {
if (controller.signal.aborted) return resolve(undefined)
runValidatorOrAdapter({
validateFn: validateObj.validate,
value: {
value: this.state.values,
formApi: this,
signal: controller.signal,
},
methodName: 'validateAsync',
adapters: [this.options.validatorAdapter as never],
})
.then(resolve)
.catch(reject)
}, onChangeAsyncDebounceMs)
})
} catch (e: unknown) {
rawError = e as ValidationError
Expand Down

0 comments on commit 9f4259f

Please sign in to comment.