shakacode / re-formality

Form validation tool for reason-react
https://re-formality.now.sh
MIT License
244 stars 36 forks source link

Async validation function for field required when creating the form definition #94

Closed johnhaley81 closed 3 years ago

johnhaley81 commented 3 years ago

Issue

When using an async validator for a field, you have to have the function fully defined when you are writing out the form in the PPX. You are also not able to use any other fields inside of the form while executing the function. This is an issue when you require more data to finish the validation (say an OAuth token) since you can't use a partially applied function, nor reference a field in the form that would carry such data.

Solution 1

You can use module functors to get around this. You have a module functor that creates the form based on another module you pass in, which that form contains the function with all of the extra necessary data to complete the call. This gets out of hand fast though. You have to fully define the module types for both the input and the output which can be difficult, you have to store the created form module in something (like React.useState) so that you aren't creating a brand new form on each render, and you have to use first-class modules in order to be able to save the form.

This works right now and it does makes working with the form quite easy after a ton of upfront work using some things that are not well documented or known in the ReScript community. Not ideal IMO

Solution 2

Allow the PPX form to take in a function that is the of the same type as the function now (i.e. fieldOutput => Js.Promise.t(result(fieldOutput error)) via some custom named param when calling useForm.

e.g.

module Form = [%form
  type submissionError = Foo;

  type input = {
    email: [@field.async] string
  };

  type output = {
    email: Email.t
  };

  let validators = {
    email: strategy: OnFirst

  let validators = {
    email: {
      strategy: OnFirstSuccessOrFirstBlur,
      validate: input => input.email->Email.validate,
      validateAsync: FormArgument
    }
  };
];

[@react.component]
let make = (~validateEmailAsync) => {
  let _ = Form.useForm(~initialState={ email: "" }, ~onSubmit={(_,_) => ()}, ~validateEmailAsync);

  React.null;
};

Thoughts?

alex35mil commented 3 years ago

@johnhaley81 Will passing metadata to all (incl. async) validators help with this problem?

johnhaley81 commented 3 years ago

Yeah, that would work well I think!

On Thu, Nov 12, 2020, 1:51 AM Alex Fedoseev notifications@github.com wrote:

@johnhaley81 https://github.com/johnhaley81 Will passing metadata https://github.com/MinimaHQ/re-formality/issues/82 to all (incl. async) validators help with this problem?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/MinimaHQ/re-formality/issues/94#issuecomment-725936083, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGT3RFWHXT4KA6UXRZTXDLSPOOXNANCNFSM4TROZXLQ .

alex35mil commented 3 years ago

Closing since #95 merged.