First, let's take a quick look at the MDN docs for Blob's constructor arguments:
Parameters
array - An iterable object such as an Array, having ArrayBuffers, TypedArrays, DataViews, Blobs, strings, or a mix of any of such
elements, that will be put inside the Blob. Note that strings here are
encoded as UTF-8, unlike the usual JavaScript UTF-16 strings.
options (Optional) - An object which may specify any of the following properties:
- type Optional - The MIME type of the data that will be stored into the blob. The default value is the empty string, ("").
This gets us far enough to understand this code in the linked answer:
var byteArray = new Uint8Array(arr);
//...
a.href = window.URL.createObjectURL(new Blob([byteArray], { type: 'application/octet-stream' }));
which is first creating a typed array of unsigned int8s, then wrapping that UInt8Array in an array and using it to construct a Blob with the specified MIME type.
In elemental2, we have these same constructors - but I think we're going to want to use a different TypedArray type here, since Java byte
s are signed, so instead let's look at elemental2.core.Int8Array
(also available at MDN for clearer documentation). We can either use a constructor to create an Int8Array
, or can use the static from(...)
method. Neither of these actually accept a byte[]
, but either want a double[]
or JsArrayLike<Double>
- from our perspective as Java developers, these seem wrong, but from JS's perspective a GWT byte[]
is usually just a plain JS array that just happens to have small Number
s in it (which map to Java double
or Double
.
So we cheat, and cast to what we actually want. The rest of the code just deals with making arrays of union types, a corner case of Elemental2 and JsInterop that we usually don't have to look closely at.
public static Blob makeBlobFromBytes(byte[] byteArray) {
// First, cast our incoming byte[] to something we can wrap in an Int8Array
JsArrayLike<Double> data = Js.uncheckedCast(byteArray);
// Then copy this data into a TypedArray
Int8Array int8Array = Int8Array.from(data);
// Finally wrap in a Blob, with the specified MIME type and other options.
// This part is a bit irritating since we have to use a union in an array:
BlobPropertyBag options = BlobPropertyBag.create();
options.setType("application/octet-stream");
Blob blob = new Blob(JsArray.of(
Blob.ConstructorBlobPartsArrayUnionType.of(int8Array)
), options);
}