1

I am working with playload cms & trying to create a doc in collection with a file, following this payload documentation article https://payloadcms.com/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

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.