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

Discussion for a new feature - Accept native FormData #83

Open
okalil opened this issue Dec 7, 2024 · 4 comments
Open

Discussion for a new feature - Accept native FormData #83

okalil opened this issue Dec 7, 2024 · 4 comments

Comments

@okalil
Copy link

okalil commented Dec 7, 2024

Context

Although it is not a web standard, it is common to use dot/bracket syntax to represent arrays and nested objects.
Some frameworks like Adonis and Express (with body parser) handle that automatically.
However, with Remix or RSC actions, that expose a native FormData object without any extra preprocessing, handling arrays and objects is not so straightforward and we would need to manually parse the FormData (or use some lib) before forwarding it to the vine validator.

async function myAction(formData: FormData) {
  const form = preprocessFormData(formData)
  const data = await vine.validate({ data: form, schema })
}

Solutions

Since it's a common case for frameworks that use the native FormData, it would be nice if vine could handle that without extra libs / developer work. I'm not sure what would be the best way to do it though, here are some ideas:

  1. The data option accepts FormData objects:
       await vine.validate({ data: formData, schema })
    In this case the validate method would check if formData is instanceof FormData and then apply the preprocessing before matching the schema.
  2. External method
      await vine.validate({ data: vine.process(formData), schema })
    Include a new method or function (name is up to discussion) to preprocess the formData before calling validate.
@DNWCloud
Copy link

I was very surprised that vinejs doesn't (it seems) support this already. Vine's docs seem to indicate that it should be stupid simple to handle form data:

Built for validating form data and JSON payloads
Serializing an HTML form to FormData or a ‌JSON object comes with its own set of quirks. For example:

Numbers and booleans are serialized as strings
Checkboxes are not booleans
And empty fields are represented as empty strings
VineJS handles all these quirks natively, and you never have to perform manual normalization in your codebase.

And yet when I try to simple run the following code:

const authSchema = vine.object({
  email: vine.string().email(),
  password: vine.string().minLength(8).maxLength(32),
});

const authValidator = vine.compile(authSchema);

const data = await authValidator.validate(formData);

I receive an error with messages:

{
    message: 'The email field must be defined',
    rule: 'required',
    field: 'email'
  },
  {
    message: 'The password field must be defined',
    rule: 'required',
    field: 'password'
  }

@okalil
Copy link
Author

okalil commented Dec 14, 2024

Yeah.. For now I created a separate class to parse the body:

const data = bodyParser.parse(formData) // handles nested fields with dot/bracket notation
const { email, password } = await vine.validate({ data, schema })

But it would be great if there was a built in function for that.

@DNWCloud
Copy link

Could we add a 1-liner like this somewhere?

data = data instanceof FormData ? Object.fromEntries(data.entries()) : data;

@thetutlage
Copy link
Contributor

The issue will be nested data/array indexes. For example: How would data.entries() will look like for the following HTML inputs.

<div>
  <label for="email-1"> Email 1 </label>
  <input type="email" id="email-1" name="users[0]['email']">
 </div>

 <div>
  <label for="email-2"> Email 2 </label>
  <input type="email" id="email-2" name="users[1]['email']">
</div>

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

3 participants