最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

next.js - How to upload file using Payload CMS REST API - Stack Overflow

programmeradmin1浏览0评论

I am working with playload cms & trying to create a doc in collection with a file, following this payload documentation article

Collection config code

import type { CollectionConfig } from 'payload'
export const DemoCollection: CollectionConfig = {
  slug: 'demoCollection',
  fields: [
    {
      type: 'text',
      name: 'title',
      label: 'Title',
    },
    { type: 'upload', name: 'image', label: 'Image', relationTo: 'media' },
  ],
}

Upload Page attached

'use client'
const FormSchema = z.object({
  title: z.string().min(2, {
    message: 'Title must be at least 2 characters.',
  }),
  image: z.instanceof(FileList),
})
const DemoPage = () => {
  const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema),
    defaultValues: {
      title: '',
    },
  })
  async function onSubmit(data: z.infer<typeof FormSchema>) {
    const formData = new FormData()
      formData.append('image', data.image[0])
    formData.append('title', data.title)
    console.log('formData', formData)
    try {
      const req = await fetch('{apiurl}/demoCollection', {
        method: 'POST',
        credentials: 'include',
        body: formData,
      })
      const data = await req.json()
      console.log('res data', data)
    } catch (err) {
      console.log(err)
    }
  }
  return (
    <div className="container">
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
          <FormField
            control={form.control}
            name="title"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Title</FormLabel>
                <FormControl>
                  <Input placeholder="Enter title" {...field} />
                </FormControl>
                <FormDescription>This is the title of your demo item.</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="image"
            render={({ field }) => (
              <FormItem>
                <FormControl>
                  <Input
                    type="file"
                    onChange={(e) => {
                      field.onChange(e.target.files)
                    }}
                  />
                </FormControl>
                <FormDescription>Upload your image file.</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />
          <Button type="submit">Submit</Button>
        </form>
      </Form>
    </div>
  )
}
export default DemoPage

error on browser

Something went wrong.

error on the server console

Cannot read properties of undefined (reading 'title')

Thanks in advance for your help

I am working with playload cms & trying to create a doc in collection with a file, following this payload documentation article https://payloadcms/docs/upload/overview#uploading-files

Collection config code

import type { CollectionConfig } from 'payload'
export const DemoCollection: CollectionConfig = {
  slug: 'demoCollection',
  fields: [
    {
      type: 'text',
      name: 'title',
      label: 'Title',
    },
    { type: 'upload', name: 'image', label: 'Image', relationTo: 'media' },
  ],
}

Upload Page attached

'use client'
const FormSchema = z.object({
  title: z.string().min(2, {
    message: 'Title must be at least 2 characters.',
  }),
  image: z.instanceof(FileList),
})
const DemoPage = () => {
  const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema),
    defaultValues: {
      title: '',
    },
  })
  async function onSubmit(data: z.infer<typeof FormSchema>) {
    const formData = new FormData()
      formData.append('image', data.image[0])
    formData.append('title', data.title)
    console.log('formData', formData)
    try {
      const req = await fetch('{apiurl}/demoCollection', {
        method: 'POST',
        credentials: 'include',
        body: formData,
      })
      const data = await req.json()
      console.log('res data', data)
    } catch (err) {
      console.log(err)
    }
  }
  return (
    <div className="container">
      <Form {...form}>
        <form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
          <FormField
            control={form.control}
            name="title"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Title</FormLabel>
                <FormControl>
                  <Input placeholder="Enter title" {...field} />
                </FormControl>
                <FormDescription>This is the title of your demo item.</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />
          <FormField
            control={form.control}
            name="image"
            render={({ field }) => (
              <FormItem>
                <FormControl>
                  <Input
                    type="file"
                    onChange={(e) => {
                      field.onChange(e.target.files)
                    }}
                  />
                </FormControl>
                <FormDescription>Upload your image file.</FormDescription>
                <FormMessage />
              </FormItem>
            )}
          />
          <Button type="submit">Submit</Button>
        </form>
      </Form>
    </div>
  )
}
export default DemoPage

error on browser

Something went wrong.

error on the server console

Cannot read properties of undefined (reading 'title')

Thanks in advance for your help

Share Improve this question edited Mar 13 at 9:59 Dinesh asked Mar 13 at 9:53 DineshDinesh 8652 gold badges19 silver badges41 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I am using payload v3, this is also working with v2. There is upload property for the collection, it is not a field. Just submit a post request with a FormData. Here is an example:

> collections/media.ts

export const Media: CollectionConfig = {
  slug: 'media',
  labels: {
    plural: 'Media',
    singular: 'Media',
  },
  access: {
    read: () => true,
    create: () => true,
  },
  fields: [
    {
      name: 'someField',
      type: 'text',
    },
  ],
  upload: true,
}

And the request itself:

const fd = new FormData()
fd.append('file', YOUR_FILE_HERE as File)
fd.append('someField', 'SOME_VALUE')

const res = await fetch('/api/media', {
      method: 'POST',
      credentials: 'include',
      body: fd,
})

const resJson = await res.json()

// Then you can update the collection file field with the new file id
const newFileId = resJson.doc.id

// Make a payload.update request to update the demoCollection with file id
...

Hope this will help.

发布评论

评论列表(0)

  1. 暂无评论