Multipart Upload
We will show you how to multipart upload with refine.
Let's start with the creation form first.
Create Form
Let's add the image field to the post creation form.
import {
  useApiUrl,
} from '@pankod/refine-core'
import {
  Upload,
  getValueFromEvent,
  Create,
  Form,
  Input,
  useForm,
} from '@pankod/refine-antd'
export const PostCreate: React.FC = () => {
  const { formProps, saveButtonProps } = useForm<IPost>()
  const apiUrl = useApiUrl()
  return (
    <Create saveButtonProps={saveButtonProps}>
      <Form {...formProps} layout="vertical">
        <Form.Item
          label="Title"
          name="title"
          rules={[
            {
              required: true,
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.Item label="Image">
          <Form.Item
            name="image"
            valuePropName="fileList"
            getValueFromEvent={getValueFromEvent}
            noStyle
          >
            <Upload.Dragger
              name="file"
              action={`${apiUrl}/media/upload`}
              listType="picture"
              maxCount={5}
              multiple
            >
              <p className="ant-upload-text">Drag & drop a file in this area</p>
            </Upload.Dragger>
          </Form.Item>
        </Form.Item>
      </Form>
    </Create>
  )
}
interface IPost {
  id: number
  title: string
  image: [
    {
      uid: string
      name: string
      url: string
      status: 'error' | 'success' | 'done' | 'uploading' | 'removed'
    },
  ]
}
We can reach the API URL by using the useApiUrl hook.
It will look like this.

What we need now is an upload end-point that accepts multipart uploads. We write this address in the action property of the Upload component.
{
  "file": "binary"
}
This end-point should be Content-type: multipart/form-data and Form Data: file: binary?.
This end-point should respond similarly.
{
  "url": "https://example.com/uploaded-file.jpeg"
}

We have to use the getValueFromEvent method to convert the uploaded files to Antd UploadFile object.
This data is sent to the API when the form is submitted.
{
  "title": "Test",
  "image": [
    {
      "uid": "rc-upload-1620630541327-7",
      "name": "greg-bulla-6RD0mcpY8f8-unsplash.jpg",
      "url": "https://refine.ams3.digitaloceanspaces.com/78c82c0b2203e670d77372f4c20fc0e2",
      "type": "image/jpeg",
      "size": 70922,
      "percent": 100,
      "status": "done"
    }
  ]
}
The following data are required for the Antd Upload component and all should be saved.
| Property | Description | 
|---|---|
| uid | Unique id | 
| name | File Name | 
| url | Download URL | 
| status | error, success, done, uploading, removed | 
Edit Form
Let's add the image field to the post editing form.
import {
  useApiUrl,
} from '@pankod/refine-core'
import {
  Upload,
  getValueFromEvent,
  Edit,
  Form,
  Input,
  useForm,
} from '@pankod/refine-antd'
export const PostEdit: React.FC = () => {
  const { formProps, saveButtonProps } = useForm<IPost>()
  const apiUrl = useApiUrl()
  return (
    <Edit saveButtonProps={saveButtonProps}>
      <Form {...formProps} layout="vertical">
        <Form.Item
          label="Title"
          name="title"
          rules={[
            {
              required: true,
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.Item label="Image">
          <Form.Item
            name="image"
            valuePropName="fileList"
            getValueFromEvent={getValueFromEvent}
            noStyle
          >
            <Upload.Dragger
              name="file"
              action={`${apiUrl}/media/upload`}
              listType="picture"
              maxCount={5}
              multiple
            >
              <p className="ant-upload-text">Drag & drop a file in this area</p>
            </Upload.Dragger>
          </Form.Item>
        </Form.Item>
      </Form>
    </Edit>
  )
}

A request, like the one below, is sent for edit form.
{
  "id": 1,
  "title": "Test",
  "image": [
    {
      "uid": "rc-upload-1620630541327-7",
      "name": "greg-bulla-6RD0mcpY8f8-unsplash.jpg",
      "url": "https://refine.ams3.digitaloceanspaces.com/78c82c0b2203e670d77372f4c20fc0e2",
      "type": "image/jpeg",
      "size": 70922,
      "percent": 100,
      "status": "done"
    }
  ]
}
This data is sent to the API when form is submitted.
{
  "title": "Test",
  "image": [
    {
      "uid": "rc-upload-1620630541327-7",
      "name": "greg-bulla-6RD0mcpY8f8-unsplash.jpg",
      "url": "https://refine.ams3.digitaloceanspaces.com/78c82c0b2203e670d77372f4c20fc0e2",
      "type": "image/jpeg",
      "size": 70922,
      "percent": 100,
      "status": "done"
    }
  ]
}
Uploading State
You may want to disable the "Save" button in the form while the upload is going on. To do this, you can use the useFileUploadState hook.
import { useApiUrl } from '@pankod/refine-core'
import {
  Upload,
  getValueFromEvent,
  useFileUploadState,
  Create,
  Form,
  Input,
  useForm,
} from '@pankod/refine-antd'
export const PostCreate: React.FC = () => {
  const { formProps, saveButtonProps } = useForm<IPost>()
  const { isLoading, onChange } = useFileUploadState()
  const apiUrl = useApiUrl()
  return (
    <Create
      saveButtonProps={{
        ...saveButtonProps,
        disabled: isLoading,
      }}
    >
      <Form {...formProps} layout="vertical">
        <Form.Item
          label="Title"
          name="title"
          rules={[
            {
              required: true,
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.Item label="Image">
          <Form.Item
            name="image"
            valuePropName="fileList"
            getValueFromEvent={getValueFromEvent}
            noStyle
          >
            <Upload.Dragger
              name="file"
              action={`${apiUrl}/media/upload`}
              listType="picture"
              maxCount={5}
              multiple
              onChange={onChange}
            >
              <p className="ant-upload-text">Drag & drop a file in this area</p>
            </Upload.Dragger>
          </Form.Item>
        </Form.Item>
      </Form>
    </Create>
  )
}
Example
npm create refine-app@latest -- --example upload-antd-multipart