I am making a web app using NextJS with TRPC. In my app I have a form that asks to select a File. What I need to do is pass the file a trpc call so I can do all the file logic in the backend and not in the front end, because I am going to make API requests and I am on a "use client" page. This is the code I have:
"use client"
import * as z from "zod"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "../ui/form"
import { Button } from "../ui/button"
import { Input } from "../ui/input"
import { trpc } from "@/app/_trpc/client"
const TrainForm = () => {
const formSchema = z.object({
file: z.instanceof(File)
})
const { mutate: uploadFile, isLoading } = trpc.uploadFile.useMutation()
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema)
})
function onSubmit(data: z.infer<typeof formSchema>) {
console.log(data.file)
// Handle file
uploadFile({
file: data.file
})
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className=" space-y-4 p-8">
<FormField
control={form.control}
name="file"
render={({ field }) => (
<Input accept="application/pdf" type="file" name="file" onChange={(e: any) => {
const file = e.target.files?.[0]
field.onChange(file)
}} />
)}
/>
<Button disabled={isLoading} type="submit">
Submit
</Button>
</form>
</Form>
);
}
export default TrainForm;
TRPC:
import { privateProcedure, publicProcedure, router } from './trpc';
import { TRPCError } from '@trpc/server'
import { db } from '@/db';
import { z } from 'zod';
export const appRouter = router({
// query to get data
// mutation to modify data
// Private
uploadFile: publicProcedure.input(z.object({
file: z.instanceof(File)
})).mutation(async ({input}) => {
// handle file
}),
});
// Export type router type signature,
// NOT the router itself.
export type AppRouter = typeof appRouter;
Errors:
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (uploadFile, line 0)
[Error] TRPCClientError: The string did not match the expected pattern.
(anonymous function) (app-index.js:32)
(anonymous function) (hydration-error-info.js:41)
(anonymous function) (mutation.mjs:167)
Thanks!!!
Passing a file to tRPC is not supported yet. You can use FormData, currently in experimental phase.