edmundhung / conform

A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js.
https://conform.guide
MIT License
1.8k stars 101 forks source link

Using parseWithZod with a formData that has an array of strings #725

Closed yoni-noma closed 1 month ago

yoni-noma commented 1 month ago

Describe the bug and the expected behavior

im sending an array of strings trough the network using formData with a value: formData.set('classifications', JSON.stringify(['foo','bar','baz'])) And when recieving it on the server(remix action) im using parseWithZod(request.formData) with a matching schema:

export function DatasetClassificationsInputSchema(): z.ZodObject<
  Properties<DatasetClassificationsInput>
> {
  return z.object({
    classifications: z.array(z.string().nullable()),
    datasetId: z.string(),
  });
}

but when looking at the outcome of:

  const submission = parseWithZod(formData, {
    schema: DatasetClassificationsInputSchema,
  });

im seeing that it doesnt parse the array corretly, it looks like this:

 {
    "status": "success",
    "payload": {
        "classifications": "[\"foo\",\"bar\",\"baz\"]",
        "datasetId": "RSBgsakUBc8WjMay1_re3"
    },
    "value": {
        "classifications": [
            "[\"foo\",\"bar\",\"baz\"]"
        ],
        "datasetId": "RSBgsakUBc8WjMay1_re3"
    }
}

What you can see here is an array that his first value is a stringify Array. instead of just array of values

Conform version

"@conform-to/react": "^1.1.5"

Steps to Reproduce the Bug or Issue

try to use parseWithZod on a formData with an array

What browsers are you seeing the problem on?

No response

Screenshots or Videos

No response

Additional context

No response

marcomuser commented 1 month ago

What's your specific use-case? Why do you set formData like this imperatively on the formData object? Just trying to understand because the result is what I had expected from looking at the example. 🤔

From my understand, with FormData array values are usually transformed to comma separated strings, e.g.:

const formData = new FormData();
formData.set("classifications", ["foo", "bar"])

would lead to a key value pair of:

["classifications", "foo, bar"]
edmundhung commented 1 month ago

I guess you are looking for formData.append() which could be used like this:

formData.append('classifications', 'foo');
formData.append('classifications', 'bar');
formData.append('classifications', 'baz');