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

Nested objects and arrays #18

Closed
02JanDal opened this issue May 7, 2022 · 3 comments
Closed

Nested objects and arrays #18

02JanDal opened this issue May 7, 2022 · 3 comments
Labels
enhancement New feature or request

Comments

@02JanDal
Copy link

02JanDal commented May 7, 2022

Really interesting library already!

There does not seem to be support for nested objects and arrays yet, AFAICT.

For example based on a schema like this:

const schema = z.object({
  name: z.string(),
  contact: z.object({ email: z.string().nonempty().email() }),
  addresses: z.array(
    z.object({
      address: z.string(),
      country: z.string()
    })
  ),
});

It seems like it should be pretty easy to do this using register etc. from react-hook-form, but it would be nice to have support for that in remix-forms.

@danielweinmann
Copy link
Contributor

Hey, @02JanDal! Thanks for creating this issue 💪

We don't have support for objects and arrays in the schema yet, but it is high on our priority list to add it :)

In the meantime, you can still use Remix Forms for the schema above, but instead of rendering a Field component, you'll need to render a custom UI directly inside of Form's children, with the help of register and other react-hook-form props. I haven't tested it yet, but I think all the client-side validations will work correctly that way.

The server-side validations do work with objects and arrays already, so you're covered on that end.

Can you please let us know if this works?

@gederer
Copy link

gederer commented May 29, 2022

Hey, @danielweinmann. I tried this with a set off checkboxes, all with the same name. This is my Zod schema:

const schema = z.object({
  name: z.string().nonempty(),
  age: z.number(),
  hobbies: z.array(z.string()).nonempty("Must have at least one hobby")
});

When I have two or more checkboxes checked, I get the correct values passed into my mutation function. But, if I have only one checkbox checked, the form doesn't submit. I (strongly!) suspect this is because a single value is passed as a scalar, rather than as an array. Do you know how I might patch this up?

Update:

Changed my Zod schema to:

const schema = z.object({
  name: z.string().nonempty(),
  age: z.number(),
  hobbies: z.union([z.string().optional(), z.array(z.string()).optional()]).optional()
    .transform(val => typeof val !== "undefined" ? Array.isArray(val) ? val : [val] : [])
});

Now, it submits correctly with a single checkbox or multiple checkboxes checked. But, when I submit with zero checkboxes checked, it focuses (but does not check) the first checkbox without submitting. Oddly, if I submit a second time after the first checkbox is focused, it does submit correctly. Not sure why.

Update 2 (Finally got it):

const schema = z.object({
  name: z.string().nonempty(),
  age: z.number(),
  hobbies:
    z.preprocess(
      val => !!val ? Array.isArray(val) ? val : [val] : [],
      z.array(z.string())
    )
});

@danielweinmann
Copy link
Contributor

Hey, @gederer! Can you share a complete example of how you made it work with us? I'm designing an API to deal with nested objects and arrays, and it would be great to contemplate your use case when thinking about it.

@felipefreitag felipefreitag added the enhancement New feature or request label Jul 15, 2022
@danielweinmann danielweinmann closed this as not planned Won't fix, can't repro, duplicate, stale Jul 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants