I'm currently transitioning my Flutter Web app to leverage JS functions via the package:web instead of dart:js and similar libraries. However, I've hit a roadblock where the JSArray<JSAny>
type isn't resolving correctly. Below is the complete code snippet:
@JS()
library image;
import 'package:flutter/services.dart';
import 'package:web/web.dart';
import 'dart:js_interop';
import 'dart:convert';
@JS('setImage')
external JSPromise _setImage(Blob data); // defined in .js file
void setImage(String data) {
final blob = Blob(
// JSArray<JSAny> is required here.
JsUint8List.from(Uint8List.fromList(base64Decode(data))),
BlobPropertyBag(type: 'image/png'),
);
_setImage(blob);
}
extension type JsUint8List._(Uint8List _) implements JSArray<JSAny> {
JsUint8List.from(this._);
}
The runtime error I'm encountering is:
Error: The representation type 'Uint8List' of extension type 'JsUint8List' must be either a subtype of the representation type 'JSArray/*1*/<Object?>' of the implemented extension type 'JSArray/*2*/<JSAny>' or a subtype of 'JSArray/*2*/<JSAny>' itself.
Could someone provide guidance on how to properly convert between Dart's Uint8List
and Blob
using the new package:web?
I attempted to create a Blob
using package:js/js.dart
, among others.
@JS()
library image;
// ignore: depend_on_referenced_packages
import 'dart:convert';
import 'package:flutter/services.dart';
// ignore: depend_on_referenced_packages
import 'package:js/js.dart';
// ignore: avoid_web_libraries_in_flutter
import 'dart:js_util';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
@JS('setImage')
external _setImage(html.Blob data);
void setImage(String data) {
final blob = html.Blob([Uint8List.fromList(base64Decode(data))], 'image/png');
_setImage(blob);
}
The code has executed successfully. However, I aim to implement it using the new package:web
. I referred to this page and to another source (specifically about extension types).
You can define the Blob class in Dart for JavaScript interop using the @JS annotation. Below is an example where I've added two arguments. You can refer to the Blob documentation and complete them if necessary. However, this should be sufficient for basic use cases:
import 'dart:typed_data';
import 'dart:js_interop';
@JS("Blob")
extension type Blob._(JSObject _) implements JSObject {
external factory Blob(JSArray<JSArrayBuffer> blobParts, JSObject? options);
factory Blob.fromBytes(List<int> bytes) {
final data = Uint8List.fromList(bytes).buffer.toJS;
return Blob([data].toJS, null);
}
external JSArrayBuffer? get blobParts;
external JSObject? get options;
}