How to FormData.getAll?
bduff9 opened this issue · comments
Hello! We just found this library a couple of weeks ago and have started trying to implement it into our application where we heavily use server actions. We ran into a case that the documentation does not mention so we are hoping there is an answer.
We have several cases in our server actions where we need to call FormData.getAll to get all inputs instead of FormData.get. How can we do this with this library?
For instance, we might have the code in the server action that looks like this:
const result = zodSchema.safeParse({
...Object.fromEntries(formData),
files: formData.getAll('files'),
});
Just in time (just merged a PR for this right now)!
Please upgrade to zsa@0.3.1
and zsa-openapi@0.0.10
The TLDR is you want to use a z.array(z.instanceof(File))
. For a more comprehensive example, we posted a new section on our docs.
"use server"
import z from "zod"
import { createServerAction } from "zsa"
export const myFilesAction = createServerAction()
.input(
z.object({
filefield: z.array(z.instanceof(File)),
}),
{
type: "state",
}
)
.handler(async ({ input }) => {
await new Promise((resolve) => setTimeout(resolve, 500))
console.log(input.filefield) // this is an array of File objects
})
in client:
"use client"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { useActionState } from "react"
import { myFilesAction } from "./actions"
export default function Example() {
let [[data, err], submitAction, isPending] = useActionState(
myFilesAction,
[null, null]
)
return (
<Card className="not-prose">
<CardHeader>
<CardTitle>Multi Entry Form</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<form action={submitAction} className="flex flex-col gap-4">
<Input name="filefield" type="file" multiple />
</form>
{isPending && <div>Loading...</div>}
{data && <p>Result: {data}</p>}
{err && <div>Error: {JSON.stringify(err.fieldErrors)}</div>}
</CardContent>
</Card>
)
}
Closing this issue now, please ping back here if something isn't working or with any further questions!