2

I am building a flutter web using old version. I am having a FileUploadInputElement. I need to get the file selected from that element.

@override
  Widget build(BuildContext context) {
    FileUploadInputElement fileUploadInputElement = FileUploadInputElement();
    ui.platformViewRegistry.registerViewFactory(
        'animation-Image-html', (int viewId) => fileUploadInputElement);



    return SizedBox(
      child: HtmlElementView(
        viewType: 'animation-Image-html',
      ),
    );
}

2 Answers2

4

You can directly use the element.files property to access the files and use the Filreader class from dart:html. I have created an example below to show you how a text file and image can be read. This example is based on FileReader examples in another post.

Accessing the file

Here element is the FileUploadInputElement reference.

element.files[0] or in case of multiple files element.files

Set up your file reader

  String option1Text = "Initialized text option1";
  Uint8List uploadedImage;
  FileUploadInputElement element = FileUploadInputElement()..id = "file_input";
  // setup File Reader
  FileReader fileReader = FileReader();

Use FileReader to read the file

fileReader.readAsText(element.files[0])

connect the listener for load event

fileReader.onLoad.listen((data) {
              setState(() {
                option1Text = fileReader.result;
              });
            });

connect error events

fileReader.onError.listen((fileEvent) {
              setState(() {
                option1Text = "Some Error occured while reading the file";
              });
            });

Use Image.memory to show images from byte array.

Image.memory(uploadedImage)

Note: In the following example we choose a file and click the respective button to handle the file reading. But the same can be achieved by connecting the logic in respective events of the FileUploadInputElement element in a similar approach. eg: element.onLoad.listen or element.onError.listen event streams.

Full Example enter image description here

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'dart:html';

class FileUploadTester extends StatefulWidget {
  @override
  _FileUploadTesterState createState() => _FileUploadTesterState();
}

class _FileUploadTesterState extends State<FileUploadTester> {
  String option1Text = "Initialized text option1";
  Uint8List uploadedImage;
  FileUploadInputElement element = FileUploadInputElement()..id = "file_input";
  // setup File Reader
  FileReader fileReader = FileReader();

  // reader.onerror = (evt) => print("error ${reader.error.code}");
  @override
  Widget build(BuildContext context) {
    ui.platformViewRegistry.registerViewFactory("add_input", (int viewId) {
      return element;
    });
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.end,
      children: <Widget>[
        FlatButton(
          color: Colors.indigoAccent,
          child: Text('ReadFile'),
          onPressed: () {
            fileReader.onLoad.listen((data) {
              setState(() {
                option1Text = fileReader.result;
              });
            });
            fileReader.onError.listen((fileEvent) {
              setState(() {
                option1Text = "Some Error occured while reading the file";
              });
            });
            fileReader.readAsText(element.files[0]);
          },
        ),
        Expanded(
          child: Container(
            child: Text(option1Text),
          ),
        ),
        Expanded(child: HtmlElementView(viewType: 'add_input')),
        Expanded(
          child: uploadedImage == null
              ? Container(
                  child: Text('Uploaded image should shwo here.'),
                )
              : Container(
                  child: Image.memory(uploadedImage),
                ),
        ),
        FlatButton(
          child: Text('Show Image'),
          color: Colors.tealAccent,
          onPressed: () {
            fileReader.onLoad.listen((data) {
              setState(() {
                uploadedImage = fileReader.result;
              });
            });
            fileReader.onError.listen((fileEvent) {
              setState(() {
                option1Text = "Some Error occured while reading the file";
              });
            });
            fileReader.readAsArrayBuffer(element.files[0]);
          },
        ),
      ],
    );
  }
}

Below

Abhilash Chandran
  • 6,803
  • 3
  • 32
  • 50
  • Very nice answer. Would you know if it's possible to change the text that appears on the button ("Choose file") and near the button ("No file choosen"). I've been trying to set ..innerHtml, ..outerHtml, and other options of the FileUploadInputElement but everything remains the same. – John Smith Optional Oct 31 '19 at 21:23
  • @JohnSmithOptional Unfortunately you can't set this if you Input type is `file`. You can refer to the available options [here](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#Properties_file). In my knowledge this could cause security issues like some random script setting a random file pah from your system and upload this file. There are however some hacky workarounds. Check this stack overflow post [here](https://stackoverflow.com/questions/16001586/change-the-no-file-chosen). – Abhilash Chandran Nov 01 '19 at 09:21
  • Thanks for the reply. You're right, this seems to be a limitation of HTML itself and not a limitation of dart:html or dart:ui. Also thanks again for the detailed answer to the original post. Very useful. – John Smith Optional Nov 01 '19 at 12:25
  • Hi, @AbhilashChandran I would like to try your answer, but I got an error ```(the name 'platformviewregistry' is being referenced through the prefix 'ui', but the name 'platformviewregistry' is being referenced through the prefix 'ui', but)```.. So, the thing that I want to know is.. in what part of your code that I can get the name of the file that I have uploaded, like your image.. I would like to get the name of ```overflow.png``` – wahyu Nov 05 '20 at 04:50
  • `FileUploadInputElement element` has attribute called `files` which is a list of [File](https://api.dart.dev/stable/2.10.3/dart-html/File-class.html) instances and this will have the `name` property which can give you the file name. Regarding the error its just an analysis error and it won't affect your runtime. For more details and a solution check [here](https://github.com/flutter/flutter/issues/41563#issuecomment-626765363) – Abhilash Chandran Nov 05 '20 at 11:10
  • How can I get the data as `ByteData`, I tried reader.readAsArrayBuffer(f); and (reader.result as ByteBuffer).asByteData(). But got `Error: Expected a value of type 'ByteBuffer', but got one of type 'NativeUint8List'` – user3875388 Jan 12 '21 at 03:19
  • @user3875388 Could you create another issue with an MRE. I am not able understand exactly what you are trying to achieve.! – Abhilash Chandran Jan 12 '21 at 14:55
  • I'm sorry for the unclear. But I now use this lib https://pub.dev/packages/file_picker and now it work... – user3875388 Jan 13 '21 at 06:36
  • How we can get the name of the picked file? – Muhammad Umair Saqib Jun 27 '22 at 04:58
1

Image Upload in Flutter Web - Working perfectly fine for me :)

 startFilePicker() async {
    FileUploadInputElement uploadInput = FileUploadInputElement();
    uploadInput.multiple = true;
    uploadInput.draggable = true;
    uploadInput.click();

    uploadInput.onChange.listen((e) {
      // read file content as dataURL
      final files = uploadInput.files;
      print(files);
      if (files != null && files.isNotEmpty) {
        for (var i = 0; i < files.length; i++) {
          FileReader reader = FileReader();
          reader.onLoadEnd.listen((e) async {
            if (reader.result != null) {
              Uint8List? _byteData = reader.result as Uint8List;
// upload the image
            }
          });
          reader.onError.listen((fileEvent) {
            Fluttertoast.showToast(
                msg: "Some Error occured while reading the file");
          });
          reader.readAsArrayBuffer(files[i]);
        }
      } else {
        Fluttertoast.showToast(msg: 'Images not selected');
      }
    });
  }