airjp73 / rvf

Easy form validation and state management for React and Remix
https://rvf-js.io
MIT License
827 stars 66 forks source link

[Feature]: arrayOfStringsWithoutBlanks #305

Closed dctanner closed 1 year ago

dctanner commented 1 year ago

What is the new or updated feature that you are suggesting?

Hey, I found that when building a form with an array of text inputs (where the user can add new inputs as needed), I needed to filter out any empty inputs from the array.

I ended up creating a new function, but this might be nice to include in zfd:

const zodArrayOfStringsWithoutBlanks: InputType<ZodArray<any>> = (
  schema = z.array(zfd.text())
) => {
  return z.preprocess((val) => {
    if (Array.isArray(val)) return val.filter(v => !!v);
    if (!val) return [];
    return [val];
  }, schema) as any;
};

Why should this feature be included?

So we can support multi text input form arrays easily.

airjp73 commented 1 year ago

I think doing it this way is going to mess with validation errors. If you do something like this for example:

// validation
items: zodArrayOfStringsWithoutBlanks(z.array(z.string().max(5)))

// example field values
'hi'
''
'bye'
'asdfadsfasdfasdfasdf'

Then the error returned by zod would end up on index 2 instead of index 3, because the preprocess is removing one item from the array.

A better approach (IMO) is to do the filtering in a transform rather than a preprocess.

items: zfd.repeatable(
  z.array(
    z.string().max(5)
  ).transform(arr => arr.filter(val => !!val))
)

For that reason, I think I'll pass on adding this into ZFD, but certainly feel free to continue using it if it works with your use case. :)