Flutter web is still in technical preview but i want to pick an image from the disk and upload it to the server. Is there anyway to add HTML, JS to my flutter web project and interact with it?
Asked
Active
Viewed 2,545 times
3 Answers
1
You need addEventListener and also need to append it for woking it on mobile safari. I answered here too.
Future<void> _setImage() async {
final completer = Completer<List<String>>();
InputElement uploadInput = FileUploadInputElement();
uploadInput.multiple = true;
uploadInput.accept = 'image/*';
uploadInput.click();
// onChange doesn't work on mobile safari
uploadInput.addEventListener('change', (e) async {
// read file content as dataURL
final files = uploadInput.files;
Iterable<Future<String>> resultsFutures = files.map((file) {
final reader = FileReader();
reader.readAsDataUrl(file);
reader.onError.listen((error) => completer.completeError(error));
return reader.onLoad.first.then((_) => reader.result as String);
});
final results = await Future.wait(resultsFutures);
completer.complete(results);
});
// need to append on mobile safari
document.body.append(uploadInput);
final List<String> images = await completer.future;
setState(() {
_uploadedImages = images;
});
uploadInput.remove();
}
This also works:
Future<void> _setImage() async {
final completer = Completer<List<String>>();
final InputElement input = document.createElement('input');
input
..type = 'file'
..multiple = true
..accept = 'image/*';
input.click();
// onChange doesn't work on mobile safari
input.addEventListener('change', (e) async {
final List<File> files = input.files;
Iterable<Future<String>> resultsFutures = files.map((file) {
final reader = FileReader();
reader.readAsDataUrl(file);
reader.onError.listen((error) => completer.completeError(error));
return reader.onLoad.first.then((_) => reader.result as String);
});
final results = await Future.wait(resultsFutures);
completer.complete(results);
});
// need to append on mobile safari
document.body.append(input);
// input.click(); can be here
final List<String> images = await completer.future;
setState(() {
_uploadedImages = images;
});
input.remove();
}

user12208004
- 1,704
- 3
- 15
- 37
-
Is there a way to specify maximum number of selection in case multiple = true ? – iAkshay Jul 10 '21 at 05:28
-
you can check the number of selection with files.length – user12208004 Jul 10 '21 at 11:24
0
This will do what you want for web. Just call it from any button and it will open the system dialog to chose the file.
import 'dart:typed_data';
import 'package:universal_html/prefer_sdk/html.dart';
import '../../../providers/form_provider.dart';
Uint8List uploadedImage;
startFilePickerWeb(ProviderForm formProvider) async {
InputElement uploadInput = FileUploadInputElement();
uploadInput.click();
uploadInput.onChange.listen((e) {
// read file content as dataURL
final files = uploadInput.files;
if (files.length == 1) {
final file = files[0];
FileReader reader = FileReader();
reader.onLoadEnd.listen((e) {
//Here I send the imatge to my Provider
formProvider.setLogoEmpresa(reader.result);
});
reader.onError.listen((fileEvent) {
print("Some Error occured while reading the file");
});
reader.readAsArrayBuffer(file);
}
});
}
The provider:
class ProviderForm extends ChangeNotifier {
Uint8List logoEmpresa;
void setLogoEmpresa(Uint8List newFile) {
logoEmpresa = newFile;
notifyListeners();
}
}
Then in your view you can render it like this, in case no imatge it show a attachement icon:
Container(
width: formProvider.logoEmpresa == null
? 70.0
: 90.0,
child: formProvider.logoEmpresa == null
? Icon(
Icons.attach_file,
size: 70.0,
color: kColorPrincipal,
)
: Image.memory(formProvider.logoEmpresa,
fit: BoxFit.fitWidth),
),
If you have any question, please ask and I'll do my best to help.

Daniel
- 1,007
- 1
- 11
- 23
-
-
It depends what you understand with sending. Do you want to share with platform specific share action? there're some packages for that, do you want to upload to an API? Then use the post action there... be more specific add if I can help I will. – Daniel Jun 12 '20 at 06:51
0
You can use image_picker_web :
dependencies:
image_picker_web: ^1.0.9
picks Images (as Widget, File or Uint8List) and Videos (as File or Uint8List)

Rudresh Narwal
- 2,740
- 3
- 11
- 21