Reputation: 969
Im currently using https://pub.dev/packages/file_picker for this function
FilePickerResult result =
await FilePicker.platform.pickFiles();
if (result != null) {
setState(() {
filePicked = result;
});
for (int i = 0; i < result.files.length; i++) {
setState(() {
listBytes.add(result.files[i].bytes);
});
}
} else {
// User canceled the picker
}
when i test on web it work successfully, however the problem occur when running on web app (in mobile) after select image it got no respond. It's hard to debug since i don't really know on how to debug for web app. My question is, can i just use the function i use on web, or is there any specific function i need to use in order for it to work in web app.
Upvotes: 1
Views: 849
Reputation: 1902
You can try this for the web app (This method should only be used for the web platform):
import '../../models/html_nonweb.dart'
if (dart.library.js) 'dart:html' as html;
Future<WebFileModel> pickWebFileModel() {
final completer = Completer<WebFileModel>();
final html.InputElement input =
html.document.createElement('input') as html.InputElement;
input
..type = 'file'
..accept = 'image/*';
input.onChange.listen((e) async {
final List<html.File> files = input.files!;
final reader = html.FileReader();
reader.readAsDataUrl(files.first);
reader.onError.listen(completer.completeError);
final Future<WebFileModel> resultsFutures =
reader.onLoad.first.then((_) => WebFileModel(
path: reader.result! as String,
type: files.first.type as String,
createdAt: DateTime.fromMillisecondsSinceEpoch(
files.first.lastModified!,
),
htmlFile: files.first,
));
final results = await resultsFutures;
completer.complete(results);
});
input.click();
return completer.future;
}
To use this code, you need to create the html_nonweb.dart file:
const document = Document();
class Document {
const Document();
Element createElement(String el) => InputElement();
}
class File {
final int? lastModified = null;
final String? type = null;
}
class Element {
const Element();
}
class InputElement extends Element {
const InputElement();
final List<File>? files = null;
Stream<Object> get onChange => Stream.empty();
set type(String type) {}
set multiple(bool multiple) {}
set accept(String s) {}
void readAsDataUrl(File file) {}
void click() {}
}
class FileReader {
Stream<void Function(Object error, [StackTrace? stackTrace])> get onError =>
Stream.empty();
void readAsDataUrl(File file) {}
Stream<Object> get onLoad => Stream.empty();
final Object? result = null;
}
And WebFileModel:
import 'dart:typed_data';
import 'html_nonweb.dart' if (dart.library.js) 'dart:html' as html;
class WebFileModel {
final String path;
final String type;
final DateTime createdAt;
final html.File? htmlFile;
final Uint8List? uIntFile;
WebFileModel({
required this.path,
required this.type,
required this.createdAt,
this.htmlFile,
this.uIntFile,
});
WebFileModel copyWith({
String? path,
String? type,
DateTime? createdAt,
html.File? htmlFile,
Uint8List? uIntFile,
}) {
return WebFileModel(
path: path ?? this.path,
type: type ?? this.type,
createdAt: createdAt ?? this.createdAt,
htmlFile: htmlFile ?? this.htmlFile,
uIntFile: uIntFile ?? this.uIntFile,
);
}
}
To get a Uint8List, you need to do the following:
final imageBase64 =media.path.replaceFirst(RegExp(r'data:image/[^;]+;base64,'), '');
final uIntFile = base64Decode(imageBase64);
Upvotes: 1