MCPcopy
hub / github.com/final-form/final-form / runFieldLevelValidation

Function runFieldLevelValidation

src/FinalForm.ts:346–398  ·  view source on GitHub ↗
(
    field: InternalFieldState,
    setError: (error: any | undefined) => void,
  )

Source from the content-addressed store, hash-verified

344 };
345
346 const runFieldLevelValidation = (
347 field: InternalFieldState,
348 setError: (error: any | undefined) => void,
349 ): Promise<any>[] => {
350 const promises = [];
351 const validators = getValidators(field);
352 if (validators.length) {
353 let error: any;
354 // Bump validation key once per validation run (all validators share same key)
355 field.asyncValidationKey++;
356 const fieldValidationKey = field.asyncValidationKey;
357 validators.forEach((validator) => {
358 const errorOrPromise = validator(
359 getIn(state.formState.values as object, field.name),
360 state.formState.values,
361 validator.length === 0 || validator.length === 3
362 ? publishFieldState(state.formState, field)
363 : undefined,
364 );
365
366 if (errorOrPromise && isPromise(errorOrPromise)) {
367 // Track async validation with per-field counter
368 field.asyncValidationCount++;
369 field.validating = true;
370 const fieldInstanceId = field.instanceId; // Capture stable instance ID
371 const promise = errorOrPromise.then((error) => {
372 const currentField = state.fields[field.name];
373 // Only mutate if the field instance is still the same (check stable instanceId)
374 if (currentField && currentField.instanceId === fieldInstanceId) {
375 // Decrement async validation counter (guard against underflow)
376 if (currentField.asyncValidationCount > 0) {
377 currentField.asyncValidationCount--;
378 }
379 // Only set validating=false if all async validations for this field are complete
380 if (currentField.asyncValidationCount === 0) {
381 currentField.validating = false;
382 }
383 // Only apply error if this validation hasn't been superseded by a newer one
384 if (fieldValidationKey === currentField.asyncValidationKey) {
385 setError(error);
386 }
387 }
388 }); // errors must be resolved, not rejected
389 promises.push(promise);
390 } else if (!error) {
391 // first registered validator wins
392 error = errorOrPromise;
393 }
394 });
395 setError(error);
396 }
397 return promises;
398 };
399
400 const runValidation = (fieldChanged: string | undefined, callback: () => void) => {
401 if (validationPaused) {

Callers 1

runValidationFunction · 0.85

Calls 3

getValidatorsFunction · 0.85
getInFunction · 0.85
publishFieldStateFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…