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

Asynchronous validate prop of FieldArray put unresolved promise as FINAL_FORM/array-error instead of resolved value #176

Open
usavkov-epam opened this issue Nov 18, 2022 · 1 comment

Comments

@usavkov-epam
Copy link

Are you submitting a bug report or a feature request?

bug report

What is the current behavior?

If we provide an asynchronous function as validate prop to FieldArray component to perform asynchronous validation of field array itself, then unresolved promise is set as FINAL_FORM/array-error for this field. This causes problems if we want to check the form for errors or display an error message because the promise, even if it resolves to "undefined", is in the form's errors object.

What is the expected behavior?

FieldArray's asynchronous validate function resolved with:

  • undefined (null) - field is valid, no errors set as FINAL_FORM/array-error
  • otherwise - resolved value set as FINAL_FORM/array-error

StackBlitz Link

https://stackblitz.com/edit/react-ts-57t92d?file=App.tsx,components%2FRepeatableField.tsx

What's your environment?

{
    "final-form": "^4.20.7",
    "final-form-arrays": "^3.0.2",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-final-form": "^6.5.9",
    "react-final-form-arrays": "^3.1.4",
  }

Other information

Synchronous validation work as expected, but not async.

@iamdey
Copy link

iamdey commented Nov 25, 2022

[edit]

Unfortunately the workaround (with useState) is not enough, the form sees the promise stored as an error and never state as valid so.

It seems that making the validator async in useFieldArray works:

cf.

const validate: FieldValidator = useConstant(
() => (value, allValues, meta) => {
if (!validateProp) return undefined
const error = validateProp(value, allValues, meta)
if (!error || Array.isArray(error)) {
return error
} else {
const arrayError = []
// gross, but we have to set a string key on the array
;((arrayError: any): Object)[ARRAY_ERROR] = error
return arrayError
}
}
)

const validate: FieldValidator = useConstant(
    // !!! First change, make validate a Promise
    () => async (value, allValues, meta) => {
      if (!validateProp) return undefined;
      // !!! Second change, resolve eventual Promise before testing if it's a valid error or an array
      const error = await Promise.resolve(validateProp(value, allValues, meta));

      if (!error || Array.isArray(error)) {
        return error;
      }
      const arrayError = [];
      // gross, but we have to set a string key on the array
      ((arrayError: any): Object)[ARRAY_ERROR] = error;

      return arrayError;
    }
  );

[archive]:
Thanks for the workaround (cf. StackBlitz link above).

For the record:

  // `meta` from FieldArray render prop
  const { error } = meta;
  const [resolvedError, setResolvedError] = React.useState();

  React.useEffect(() => {
    Promise.resolve(error).then(setResolvedError);
  }, [error]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants