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

ArrayBuffer / Blob constructor conflict #56

Closed
panthershark opened this issue Feb 8, 2019 · 4 comments
Closed

ArrayBuffer / Blob constructor conflict #56

panthershark opened this issue Feb 8, 2019 · 4 comments

Comments

@panthershark
Copy link

We have a situation where we fetch binary data with http, then prompt the user, then use Download.bytes to allow the user to save the file.

In IE11, using expectBytesResponse yields InvalidStateException b/c Blobs cannot be initialized from array buffers. This is because expectBytesResponse sets xhr.responseType = 'arraybuffer'.

Run this in IE11 to see the Blob constructor issue in isolation.
new Blob( new ArrayBuffer([123]), { type: 'application/*' } );

We were able to solve the problem by creating a new expect factory function like this.

expectBlobResponse : (Result x a -> msg) -> (Http.Response Bytes -> Result x a) -> Http.Expect msg
expectBlobResponse toMsg toResult =
    Elm.Kernel.Http.expect "blob" identity (toResult >> toMsg)

We really don't want people to use Elm.Kernel inside of their application code so I'm gonna submit a PR to add this to the library.

Please let me know what you think. :)

@evancz
Copy link
Member

evancz commented Feb 11, 2019

There is no "blob" concept in Elm, so I would rather not expose a function like this in Elm itself.

Is there any way to detect if it is an IE browser and do this trick only in that situation?

E.g. If elm/file#7 fixes elm/file#5 as well, why is this preferable to that?

@panthershark
Copy link
Author

yeah.. the naming is kinda tricky, but I'll try to clear up what is happening. It is a cross-cutting concern of elm/http and elm/file.

The underlying js thing that happened
expectBytes sets xhr.responseType = 'arraybuffer' which is what causes the problem when trying to stream the bytes using Download.bytes. In turn, IE doesn't like new Blob(arraybuffer) from here - https://github.com/elm/file/blob/master/src/Elm/Kernel/File.js#L49

To summarize,

  1. browser runtime generates arraybuffer from the xhr internals
  2. elm/file or elm/bytes copies it around in kernel code
  3. Download.bytes attempts to convert it using new Blob() which makes an IE InvalidStateError

This might be a decent approach, but BlobBuilder is a deprecated api interface. I'm not sure how much y'all care about that - elm/file#7

For context, this is not a serious issue for our app. The OG bug report for this was elm/file#5

The application scenario was:
A user needs to be prompted when downloading a file. The app was downloading the bytes and holding them in memory until the user responds to the prompt.

Our code was changed to do this
Our app changed the implementation to simply initiate the download after the prompt.


I was helping out with troubleshooting the original bug report on our end. I do not have a strong feeling about whether this code should be accepted. I did think it was worth a conversation.

@panthershark
Copy link
Author

Closing this issue at Evan's request as the SSCCE is here.
#58

@evancz
Copy link
Member

evancz commented Feb 12, 2019

I think it makes sense to use #58 as the canonical statement of this problem. Thanks again for creating that!

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