elm / http

Make HTTP requests in Elm
https://package.elm-lang.org/packages/elm/http/latest
BSD 3-Clause "New" or "Revised" License
154 stars 46 forks source link

Add a FilePart tag to the Http.Part type and a filePart function to make one #45

Closed billstclair closed 5 years ago

billstclair commented 6 years ago

I recently wrote some code to upload an image file, selected with an <input type='file'> element. Creating that element and processing a change event from it is easy to do in elm/http. What's harder is posting the contents.

I did it with a custom element and a patch to XMLHttpRequest.send(), to enable binary data if it sees a header that looks like an image (otherwise, a binary string gets converted to UTF-8, mangling some of its single bytes into two bytes). That's done by the CustomElement.FileListener module in billstclair/elm-custom-element, and its corresponding site/js/file-listener.js JavaScript file.

It would be much nicer to send the file using the standard mechanism for that, FormData.append with the File object inside the <input type='file'> element. That would enable large uploads, instead of loading the entire file into memory as my custom element does. And user code would be pure Elm.

The API would be very simple.

Change the Part type, by adding a FilePart option:

type Part
  = StringPart String String
  | FilePart String String

Add a filePart function, whose second String arg is the <id> of the <input type='file' id='<id>'> element.

filePart : String -> String -> Part
filePart =
  FilePart

Elm.Kernel.Http.multipart would have to change to recognize a FilePart, and look up the input element, ensure that it's of type file, grab it's files property, and call formData.append() for each File element of that array.

I'm happy to do this, and submit it as a pull request, but only if somebody on the Elm team assures me that it's likely to be accepted.

evancz commented 5 years ago

These features exist with the changes outlined in this blog post.

billstclair commented 5 years ago

Yay! Thank you, Evan!