I'm trying to migrate my Flutter Web app to use the package:web instead of dart:js and similar libraries. However the JSArray<JSAny>
type isn't resolving correctly in the code which defines the extension type of JSArray
:
@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.
How can I properly convert between Dart's Uint8List
and Blob
using the new package:web?
Previously I created a Blob
by using package:js/js.dart
.
@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 had executed successfully. Now I aim to implement by 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With