COMMUNITY

JS: Using blob

Hello there!

I’m attempting to use blob to save an image. I believe the syntax is throwing me off.

function new( ?blobParts : Array<haxe.extern.EitherType<js.lib.ArrayBuffer,haxe.extern.EitherType<js.lib.ArrayBufferView,haxe.extern.EitherType<Blob,String>>>>, ?options : BlobPropertyBag ) : Void;

Does anyone have an example of calling this?

In JS, it would be something like:
Blob([image], {type : 'image/png'})

Thanks!

You use it in the same way you would in javascript:

import js.html.Blob;
// ...
var blob = new Blob(["Hello, world!"], {type: "text/plain"});

It’s a constructor so you need to append the new keyword.

The first argument of the constructor is of type

Array<
  EitherType<
    ArrayBuffer,
    EitherType<
      ArrayBufferView,
      EitherType<
        Blob,
        String
      >
    >
  >
>

EitherType<A,B> will accept values of type A or B, in this case it is chained multiple times to accept 4 different types.

That means the first argument is an Array which takes elements of type ArrayBuffer, ArrayBufferView, Blob or String.

2 Likes

You would think I would have understood how to chain EitherType before today!

Being an extern, haxe.extern.EitherType doesn’t have potential runtime implications like haxe.ds.Either. You can actually see it’s quite a simple implementation.

Personally, I think the syntax of the nested types is a little messy, and makes for illegible error messages. So it’s possible to write your own abstracts to describe 3, 4, or N possibilities.

abstract AnyOf3<T1, T2, T3>(Dynamic) from T1 to T1 from T2 to T2 from T3 to T3 {}
abstract AnyOf4<T1, T2, T3, T4>(Dynamic) from T1 to T1 from T2 to T2 from T3 to T3 from T4 to T4 {}

And / or you can also alias them to something sensible:

typedef StringOrIntOrFloat = AnyOf3<String, Int, Float>;
typedef StringOrIntOrFloat = EitherType<String, EitherType<Int, Float>>;

Which results in friendly error messages like, Bool should be StringOrIntOrFloat

e.g. https://try.haxe.org/#c5b39

I find this approach quite nice. Alternatively one can also roll their own domain-specific abstracts, e.g. https://github.com/hxdefold/hxdefold/blob/04b6fb2864ee5b4af2017ba4b097c649979f1ede/src/defold/Go.hx#L361

In this case with Blob constructor, wouldn’t it be preferable to use @:overload?
Are there clear guidelines on what and when we should choose between @:overload, EitherType, or Abstract for externs?

Thank you all very much!

This is all I had to do:
var blobObj = new Blob([pixels.bytes.getData()], {type: "image/png"});

Now I just need to figure out how to save this blob to my local drive…