remix icon indicating copy to clipboard operation
remix copied to clipboard

unstable_parseMultipartFormData nulls all non-file formdata fields

Open sidasmo opened this issue 2 years ago • 3 comments

What version of Remix are you using?

1.5.1

Steps to Reproduce

Installation

npx create-remix@latest ? Where would you like to create your app? ./remix-upload-test1.5.1 ? What type of app do you want to create?Just the basics ? Where do you want to deploy? Choose Remix if you're unsure; it's easy to change deployment targets. Remix App Server ? Do you want me to run npm install? (Y/n) y

Changes

change routes/index.ts to:

import type { ActionFunction } from '@remix-run/node'
import {
  redirect,
  unstable_createFileUploadHandler,
  unstable_parseMultipartFormData,
} from '@remix-run/node'
import { Form } from '@remix-run/react'

export const action: ActionFunction = async ({ request }) => {
  const uploadHandler = unstable_createFileUploadHandler({
    directory: './public/uploads',
    file: ({ filename }) => filename,
  })

  const formData = await unstable_parseMultipartFormData(request, uploadHandler)

  const title = formData.get('title')
  const fileId = formData.get('file')
  console.log('title', title, 'file: ', fileId)
  return redirect(``)
}

export default function Index() {
  return (
    <div>
      <h1>Upload Test</h1>
      <Form method='post' encType='multipart/form-data'>
        <label htmlFor='title'>Title</label>
        <input type='text' name='title' id='title' />

        <label htmlFor='file'>File</label>
        <input type='file' id='file' name='file' accept='application/pdf' />

        <button type='submit'>Submit</button>
      </Form>
    </div>
  )
}

Expected Behavior

I was expecting to get the title with formData.get('title') as i had sent it in the post request. but i got:

title:  null file:  NodeOnDiskFile [File] {
  lastModified: 0,
  webkitRelativePath: '',
  filepath: 'public/uploads/example.pdf',
  type: 'application/pdf',
  slicer: undefined,
  name: 'example.pdf'
}

Actual Behavior

Post The post request goes through with 200:

-----------------------------
Content-Disposition: form-data; name="title"

Test title
-----------------------------
Content-Disposition: form-data; name="file"; filename="example.pdf"
Content-Type:application/pdf

However, the console.log on title gives me null

sidasmo avatar Jun 07 '22 19:06 sidasmo

Can you test the answer provided here? https://github.com/remix-run/remix/issues/3238#issuecomment-1135147298

If it works, then we need to properly document this change

machour avatar Jun 08 '22 06:06 machour

thx very much, with the following changes to the uploadHandler it works:

const uploadHandler = unstable_composeUploadHandlers(
    unstable_createFileUploadHandler({
      directory: './public/uploads',
      file: ({ filename }) => filename,
    }),
    unstable_createMemoryUploadHandler()
  )

sidasmo avatar Jun 08 '22 18:06 sidasmo

facing this issue after writing a multi handler uploadHandler.

const uploadRamsHandler = unstable_composeUploadHandlers(
        unstable_createFileUploadHandler({
            maxPartSize: 25_000_000,
            directory: './private/rams/'
        }), 
        unstable_createMemoryUploadHandler()
    );

    const uploadAssociationsHandler = unstable_composeUploadHandlers(
        unstable_createFileUploadHandler({
            maxPartSize: 25_000_000,
            directory: './private/associations/'
        }), 
        unstable_createMemoryUploadHandler()
    );

    const uploadHandler: UploadHandler = async(args) => {
        if (args.name === "rams") {
            return uploadRamsHandler(args);
        } else if (args.name === "associations") {
            return uploadAssociationsHandler(args);
        }
    };

    const form = await unstable_parseMultipartFormData(request, uploadHandler);

Which then results in form.get("name") being null.

aaronduce avatar Oct 19 '22 10:10 aaronduce