8

I want to upload files using Flutter web, but I encountered some problems, my steps are as follows:

/// choose file
  void _chooseFile() {
    InputElement uploadInput = FileUploadInputElement();
    uploadInput.accept = ".mp4";
    uploadInput.multiple = true;
    uploadInput.click();
    uploadInput.onChange.listen((event) {
      final files = uploadInput.files;
      if (files.length == 1) {
        final file = files[0];
        final reader = FileReader();
        reader.onLoadEnd.listen((event) {
          print('loaded: ${file.name}');
          print('type: ${reader.result.runtimeType}');
          print('file size = ${file.size}');
          _uploadFile(file);
        });
        reader.onError.listen((event) {
          print(event);
        });
        reader.readAsArrayBuffer(file);
      }
    });
  }

/// upload file
/// file: in dart:html package not in dart:io package
  void _uploadFile(File file) async {
    FormData data = FormData.fromMap({
      'file': MultipartFile.fromBytes(
        List<int>, // -----------------------------> problem line
        filename: file.name,
      )
    });
    Dio dio = new Dio();
    dio.post('upload file url', data: data, onSendProgress: (count, total) {
      print('$count ==> $total');
    }).then((value) {
      print('$value');
    }).catchError((error) => print('$error'));
  }

The problem is that MultipartFile.fromBytes(List<int> value, {...}), but I don't know how to conver file ( in dart:html not in dart:io ) to List<int>.

Thanks!!!

2
  • What does print('type: ${reader.result.runtimeType}'); print? Commented Jan 27, 2020 at 15:13
  • How did you solve this? Commented Dec 12, 2020 at 4:56

1 Answer 1

2

You need to convert the reader, as below:

List<int> _selectedFile;
Uint8List _bytesData;

void _handleResult(Object result) {
    setState(() {
      _bytesData = Base64Decoder().convert(result.toString().split(",").last);
      _selectedFile = _bytesData;
    });
  }

call the func:

_handleResult(reader.result);

then, pass _bytesData to your MultipartFile.fromBytes(...) or have return func type as List<int> and call it anywhere you need.

For example, this is what I have done to get the image:

List<int> imageFileBytes;

    /// Browse Image:
  _setImage(int index) async {
    html.InputElement uploadInput = html.FileUploadInputElement();
    uploadInput.multiple = false;
    uploadInput.draggable = true;
    uploadInput.accept = 'image/*';
    uploadInput.click();
    html.document.body.append(uploadInput);
    uploadInput.onChange.listen((e) {
      final files = uploadInput.files;
      final file = files[0];
      final reader = new html.FileReader();
      reader.onLoadEnd.listen((e) {
        var _bytesData = Base64Decoder().convert(reader.result.toString().split(",").last);
        setState(() {
          imageFileBytes = _bytesData;
        });
      });
      reader.readAsDataUrl(file);
    });

    uploadInput.remove();
  }
Sign up to request clarification or add additional context in comments.

3 Comments

I am trying to implement this solution and I get this error trying to decode as Base64String any file type: loaded: source.gif type: Uint8List file size = 616456 Error: FormatException: Invalid character (at character 1) 59] ^
I added an example that works for me. Get the parts you need to have List<int>. @JasonPerfetto
Sorry for not following up but I was able to use this pattern successfully, but I had to adapt it to initialize my reader onLoadEnd listeners to happen in initState

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.