Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing all form values from field validate function in React-Final-Form

I am creating wrapped versions of the React-Final-Form field component, essentially creating shareable types of fields to speed development at my company. As a part of that, I wanted to create a group of checkboxes, requiring at least one to be checked - but when I attempt to write the validate function, I only seem to have access to the current field.

  1. Based on some other answers and the API documentation, I thought that the validate function received three parameters - validateMyField(value, allValues, fieldState).

When I passed my function to a given field, I get the following:

const mustPickAtLeastOne = (value, allValues, fieldState) => {
  console.log(value) //output: false
  console.log(allValues) //output: undefined
  console.log(fieldState) //output: undefined
}
  1. I was able to get the validation functional by simply adding a marker class to my checkbox fields, and then using a validation function like this:
const mustPickAtLeastOne = () => {
  const numberChecked = document.querySelectorAll("." + markerclass + " input[type=\"checkbox\"]:checked").length;
  return (numberChecked === 0 ? atLeastOneRequiredMsg : undefined);
}

This option is functional from a browser perspective, but smells pretty bad (both because I am attempting to interact with the underlying DOM nodes directly, and because I then can't test this via Jest/Enzyme - so I am missing unit test coverage to know if I break this in the future).

I am using React-Final-Form 6.3.0/Final-Form 4.16.1 - is there something wrong elsewhere, or why can't I get allValues in my validate function? Or is there an entirely better way to implement my "require at least one of these" validation?

like image 206
Rich Rein Avatar asked Dec 06 '25 14:12

Rich Rein


1 Answers

Unfortunately, I had been starting off with the example at https://codesandbox.io/s/k10xq99zmr (making use of the composeValidators function) - as I wanted to allow consumers of my component to provide custom validation functions, as well as have the component itself have one or more built-in validations (and then take the combination of all of the above to pass to the underling field validate property)...which meant that the answer was staring me right in the face:

//...
const composeValidators = (...validators) => value =>
  validators.reduce((error, validator) => error || validator(value), undefined);
///...

I corrected it to use the following:

//...
const composeValidators = (...validators) => (value, allValues, fieldState) =>
  validators.reduce((error, validator) => error || validator(value, allValues, fieldState), undefined);
///...

Meaning that despite the underlying Final-Form implementation providing all three arguments to each assigned validator function, my use of the composeValidators sample was passing the current field value along...while throwing out/ignoring the other two.

like image 87
Rich Rein Avatar answered Dec 10 '25 23:12

Rich Rein