Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No method for creating fileParts from non-File types #63

Open
paul-freeman opened this issue Jul 13, 2019 · 3 comments
Open

No method for creating fileParts from non-File types #63

paul-freeman opened this issue Jul 13, 2019 · 3 comments

Comments

@paul-freeman
Copy link

The https://github.com/elm/file package provides methods for downloading strings and bytes as files, but similar methods are not included with this package. This makes it difficult for an application to generate files that can be posted with Http.multipartBody.

Expected behavior would be to shortcut these (UX-poor) steps:

  1. File.Download.bytes (have user download file)
  2. File.Select.file (have user select the same file)
  3. Http.filePart (create a file part)
  4. Http.post (post to server)

The net result of the above steps is essentially nothing more than attaching a name to a Blob, resulting in a File. Similar steps would be used for string data.

One possible solution might be to add a function:
bytesPartToFilePart : String -> Part -> Part
to explicitly name a bytes blob.

A second solution might be to add functions to go directly from strings and bytes to file bodies.

I am proposing this change as I feel it is a relatively simple change that will open up a large variety of HTTP-based storage options for future Elm applications. I am personally exploring decentralized application file storage via IPFS and have hit a few walls from not having this feature.

@paul-freeman
Copy link
Author

I will also add that this issue can be summarized as an attempt to complete the example listed in the documentation for Http.Body.bytesBody.

For example, you could create an archive.zip file and send it along like this

Afterwards, sample code is provided, but makes no mention as to how those bytes come to be named archive.zip (presumably through server-side code).

@evancz
Copy link
Member

evancz commented Jul 16, 2019

I'm having trouble understanding the thing you want to do, so I am going to try to say what I understand.

There are a couple ways to create Part values right now:

  • Turning a File into a Part with filePart
  • Turning Bytes into a Part with bytesPart

I believe the difference in the HTTP request produced is whether a file name is associated with the part in the body. You want to send a file you made in browser though, so it is annoying that there is not an easy way to create a part with custom bytes and a custom file name.

Is that correct?

If so, I think the path would be to add functions to the File module for creating files locally. Something like File.fromBytes : String -> String -> Bytes -> File and an equivalent one for fromString. I'll need to get back into the whole File API in JS to see exactly what information is needed to make this reliable, but that's the direction that jumps out to me.

Note: I'm not sure when HTTP and files will get another batch of work, so I recommend using ports in the meantime.

@paul-freeman
Copy link
Author

You want to send a file you made in browser though, so it is annoying that there is not an easy way to create a part with custom bytes and a custom file name.

Absolutely correct.

Something like File.fromBytes : String -> String -> Bytes -> File and an equivalent one for fromString.

Yes. I think this would be ideal and simple to understand.

This SO post seems to indicate that a Blob and a File are nearly identical, suggesting this (slightly edited by me) JS transformation:

function blobToFile(theBlob, fileName){
    theBlob.lastModified = new Date();
    theBlob.name = fileName;
    return theBlob;
}

Basically, you just add the filename and date. Technically, the definition of File lists 4 fields not inherited from Blob, but 1 is deprecated and 1 is non-standardized. I think the change would be straightforward.

More than happy to use ports in the meantime. And would be happy to submit a PR if requested. :)

As background, I'm working for a decentralized messaging app startup Sylo. The browser version of our app is being written in Elm (we've got about 10K LOC) and will be released soon. My need for a resolution to this issue stems from my desire to give back to the Elm community. We use many Web RPC services, and if I can turn some of them into Elm packages, I would enjoy being able to do that for everyone. Specifically blocked are a number of improvements to the paul-freeman/elm-ipfs package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants