4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

trpcでFormData(画像等)を送信する

Last updated at Posted at 2023-08-01

trpcは基本json形式のみしか送受信は対応していませんが、
experimentalでFormDataが2023/04頃に対応されているため、やってみた。
※主な用途としては画像のアップロードなどで必要になると思います。

公式のサンプル

基本はサンプル通りだがzod-form-dataが結構やっかい
https://www.npmjs.com/package/zod-form-data

以下の例のようなシンプルなものならいいが、挙げられていない型の例を書いてみる

 import { zfd } from 'zod-form-data'; 
  
 if (typeof window === 'undefined') { 
   const undici = require('undici'); 
   globalThis.File = undici.File as any; 
 } 
  
 export const uploadFileSchema = zfd.formData({ 
   name: zfd.text(), 
   image: zfd.file(), 
 }); 

booleanはundefinedの場合にfalse、trueは任意の文字列に変更できる
https://www.npmjs.com/package/zod-form-data#checkbox
objectの場合はzodを使いつつzfdで中身を定義していく

const TestSchema = zfd.formData({
  optionalText: zfd.text().optional(),
  booleanData: zfd.checkbox({ trueValue: 'true' }),
  stringArray: zfd.repeatable(z.array(zfd.text())),
  objectArray: zfd.repeatable(z.array(XXXSchema)),
});

const XXXSchema = z.object({
  text: zfd.text(),
  file: zfd.file(z.instanceof(File).optional()),
});

React側での送信イメージ

 const formMutate = trpc.testForm.useMutation();
  
 const submit = () => {
    const formData = new FormData();
    formData.append('name', name);
    if (optionalText) {
      formData.append('optionalText', optionalText);
    }
    if (image.file) {
      formData.append('file', image.file, image.file.name);
    }
    formMutate.mutate(formData);
 };
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?