[Remix+Zod] How to deal with a user-managed array of objects? #288
-
I have a form with a few normal/flat fields, but one field that is an array of objects (in my Zod schema). Certain user interactions can add an object to this array, modify an exist member of the array, or remove an item from the array. const schema = z.object({
stuff: z.string(),
whatever: z.string(),
items: z
.object({
title: z.string({ required_error: 'Title is required' }),
description: z.string({ required_error: 'Description is required' }),
})
.array(),
}); I'm currently down the following road:
I was about to move on to implementing updates and deletes, but this feels a bit off for some reason and I wanted to check and see if there might be a better approach to the concept of managing a dynamic array of objects to be submitted when using Conform. Am I on the right track, or is there a better/more idiomatic way? P.S., |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
I guess your are dealing with multiple select like dropdown that managing the items here. Since this wont be supported without JS anyway, it's fine to just pass the array to the server as a JSON: // Assume you are managing the state in useState()
const [items, setItems] = useState(...)
// Just send the array to the server as a JSON
<input type="hidden" name={fields.items} value={JSON.stringify(items)} />
// Then parse the JSON in your zod schema through a preprocess
const schema = z.object({
// ...
items: z.preprocess(
value => JSON.parse(value),
z
.object({
title: z.string({ required_error: 'Title is required' }),
description: z.string({ required_error: 'Description is required' }),
})
.array()
.min(1, 'Please select at least 1 items'),
}); One thing to note here is that Conform map zod errors based on its internal path. If the title of the first item is missing, the required message wont show up on your |
Beta Was this translation helpful? Give feedback.
I guess your are dealing with multiple select like dropdown that managing the items here. Since this wont be supported without JS anyway, it's fine to just pass the array to the server as a JSON: