I don't know why the author did wrap his Uint8Array in a new one... note that I don't really know either the deprecated BlobBuilder API, but one typo I can see in your code is that you need to wrap your TypedArray in a normal Array:
new Blob([new Uint8Array(buffer, byteOffset, length)]);
The Blob() constructor takes a blobParts sequence as first parameter, and then searches for BufferSource, USVStrings and Blob elements in this sequence. So when you pass a TypedArray, it will actually iterate over all the entries of this TypedArray and treat these as USVString (and thus convert their numerical value to UTF-8 strings in the Blob). That's rarely what you want, so better always pass an Array in this constructor.
Note that if you don't need to slice the buffer, it's probably better to directly pass it instead of using an intermediary Uint8Array (but still in a normal Array):
new Blob([buffer]);
Answer from Kaiido on Stack Overflowjavascript - Trouble changing a Uint8Array into a blob - Stack Overflow
javascript - How to go from Blob to ArrayBuffer - Stack Overflow
javascript - How to convert Uint8Array to image - Stack Overflow
Javascript - Save typed array as blob and read back in as binary data - Stack Overflow
I don't know why the author did wrap his Uint8Array in a new one... note that I don't really know either the deprecated BlobBuilder API, but one typo I can see in your code is that you need to wrap your TypedArray in a normal Array:
new Blob([new Uint8Array(buffer, byteOffset, length)]);
The Blob() constructor takes a blobParts sequence as first parameter, and then searches for BufferSource, USVStrings and Blob elements in this sequence. So when you pass a TypedArray, it will actually iterate over all the entries of this TypedArray and treat these as USVString (and thus convert their numerical value to UTF-8 strings in the Blob). That's rarely what you want, so better always pass an Array in this constructor.
Note that if you don't need to slice the buffer, it's probably better to directly pass it instead of using an intermediary Uint8Array (but still in a normal Array):
new Blob([buffer]);
var buffer = new ArrayBuffer(32);
new Blob([buffer]);
so the Uint8Array should be
new Blob([new Uint8Array([1, 2, 3, 4]).buffer]);
You can use FileReader to read the Blob as an ArrayBuffer.
Here's a short example:
var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function(event) {
arrayBuffer = event.target.result;
};
fileReader.readAsArrayBuffer(blob);
Here's a longer example:
// ArrayBuffer -> Blob
var uint8Array = new Uint8Array([1, 2, 3]);
var arrayBuffer = uint8Array.buffer;
var blob = new Blob([arrayBuffer]);
// Blob -> ArrayBuffer
var uint8ArrayNew = null;
var arrayBufferNew = null;
var fileReader = new FileReader();
fileReader.onload = function(event) {
arrayBufferNew = event.target.result;
uint8ArrayNew = new Uint8Array(arrayBufferNew);
// warn if read values are not the same as the original values
// arrayEqual from: http://stackoverflow.com/questions/3115982/how-to-check-javascript-array-equals
function arrayEqual(a, b) { return !(a<b || b<a); };
if (arrayBufferNew.byteLength !== arrayBuffer.byteLength) // should be 3
console.warn("ArrayBuffer byteLength does not match");
if (arrayEqual(uint8ArrayNew, uint8Array) !== true) // should be [1,2,3]
console.warn("Uint8Array does not match");
};
fileReader.readAsArrayBuffer(blob);
fileReader.result; // also accessible this way once the blob has been read
This was tested out in the console of Chrome 27—69, Firefox 20—60, and Safari 6—11.
Here's also a live demonstration which you can play with: https://jsfiddle.net/potatosalad/FbaM6/
Update 2018-06-23: Thanks to Klaus Klein for the tip about event.target.result versus this.result
Reference:
- https://developer.mozilla.org/en-US/docs/Web/API/FileReader#readAsArrayBuffer()
- https://www.w3.org/TR/FileAPI/#dfn-readAsArrayBuffer
The Response API consumes a (immutable) Blob from which the data can be retrieved in several ways. The OP only asked for ArrayBuffer, and here's a demonstration of it.
var blob = GetABlobSomehow();
// NOTE: you will need to wrap this up in a async block first.
/* Use the await keyword to wait for the Promise to resolve */
const arrayBuffer = await new Response(blob).arrayBuffer();
Alternatively you could use this:
new Response(blob).arrayBuffer().then((arrayBuffer) => {
// do something with the arrayBuffer
});
Note: This API isn't compatible with older (ancient) browsers so take a look to the Browser Compatibility Table to be on the safe side ;)
As it turns out, the problem was that I had a syntax error in the creation of the Blob.
The corrected code looked like:
var blob = new Blob([myArr], {type: "octet/stream"});
I'm not really sure why if I am already passing an ArrayBuffer argument. Why I need bracket notation? Seems redundant?
According to Mozilla
https://developer.mozilla.org/en-US/docs/Web/API/Blob#Example_for_creating_a_URL_to_a_typed_array_using_a_blob
var blob = new Blob([typedArray.buffer], {type: 'application/octet-stream'});