1

I am trying to upload upload multiple images to Rest API in flutter. the code i have written is given below:

  final List<File> _image = [];
  Future<Future<bool?>?> uploadImage(filePath, url) async {

  if (_image.length > 0) {
  for (var i = 0; i < _image.length; i++) {
    print(_image.length);
    var request =
        http.MultipartRequest('POST', Uri.parse(url + _scanQrCode));
    print(Uri.parse(url + _scanQrCode));
    request.files.add(http.MultipartFile.fromBytes(
      'picture',
      File(_image[i].path).readAsBytesSync(),
      filename: _image[i].path.split("/").last
    ));
    var res = await request.send();
      var responseData = await res.stream.toBytes();
      var result = String.fromCharCodes(responseData);
      print(_image[i].path);
  }

  _submitedSuccessfully(context);
}else{
  return Fluttertoast.showToast(
      msg: "Please Select atleast one image",
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
      timeInSecForIosWeb: 1,
      backgroundColor: Colors.red,
      textColor: Colors.white,
      fontSize: 16.0
  );
}
}

The code is not working, the image is not getting uploaded. Please anyone help me to solve this problem

7 Answers 7

3

This method can simple help to upload multipe image

final uploadList = <MultipartFile>[];
for (final imageFiles in imageFileList!) {
    uploadList.add(
        await MultipartFile.fromFile(
            imageFiles.path,
            filename: imageFiles.path.split('/').last,
            contentType: MediaType('image', 'jpg'),
        ),
    );
}
Sign up to request clarification or add additional context in comments.

Comments

2

First you create to variable

  List<File>? imageFileList = [];
 List<dynamic>? _documents = [];

this method call when you pick image from gallery

  pickMultipleImage(ImageSource source) async {
try {
  final images = await picker.pickMultiImage(
      maxWidth: 600, maxHeight: 600, imageQuality: 50);
  if (images == null) return;
  for (XFile image in images) {
    var imagesTemporary = File(image.path);
    imageFileList!.add(imagesTemporary);
  }
} catch (e) {
  
}

}

this call when you pressed button for sending image to server

   for(int i=0; i< _imageFileList!.length; i++ ){
        var path = _imageFileList![i].path;
        _documents!.add(await MultipartFile.fromFile(path,
           filename: path.split('/').last));
                    }
 var payload = dio.FromData.fromMap({   'documents': _documents});

Dio() response = Dio.post(url, data: payload);

Comments

1

change your code to :

final List<File> _image = [];
Future<Future<bool?>?> uploadImage(String url) async {
     // create multipart request
     var request = http.MultipartRequest('POST', Uri.parse(url + _scanQrCode));
     
     
      if (_image.length > 0) {
        for (var i = 0; i < _image.length; i++) {
          request.files.add(http.MultipartFile('picture',
          File(_image[i].path).readAsBytes().asStream(), File(_image[i].path).lengthSync(),
          filename: basename(_image[i].path.split("/").last)));
        }
        
        // send
        var response = await request.send();

      
        // listen for response
        response.stream.transform(utf8.decoder).listen((value) {
          debugPrint(value);
         _submitedSuccessfully(context);
       });
    }
    else{
  return Fluttertoast.showToast(
      msg: "Please Select atleast one image",
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
      timeInSecForIosWeb: 1,
      backgroundColor: Colors.red,
      textColor: Colors.white,
      fontSize: 16.0
     );
   }
}

3 Comments

Getting error on basename
It should not give an error message unless it has an item from the null value list
for your error on basename @abdul do the following import 'package:path/path.dart' as path; and then filename: basename(_image[i].path.split("/").last)));
0

this package ease your work, flutter_uploader:

final uploader = FlutterUploader();

final taskId = await uploader.enqueue(
  url: "your upload link", //required: url to upload to
  files: [FileItem(filename: filename, savedDir: savedDir, fieldname:"file")], // required: list of files that you want to upload
  method: UploadMethod.POST, // HTTP method  (POST or PUT or PATCH)
  headers: {"apikey": "api_123456", "userkey": "userkey_123456"},
  data: {"name": "john"}, // any data you want to send in upload request
  showNotification: false, // send local notification (android only) for upload status
  tag: "upload 1"); // unique tag for upload task
);

1 Comment

flutter_uploader is not Dart 3 compatible and platform support is unknown. I'm not sure I'd recommend it.
0

I was facing the same problem and I used the techniques mentioned in most answers but it kept on sending just one of the images I am uploading instead of sending all. So what I did was simple. Just like HTML fields, I used an array field name. Take a look at the code below:

final List<http.MultipartFile> photos = <http.MultipartFile>[];
  if (carFormModel.photos != null && carFormModel.photos!.length > 0) {
    await Future.forEach(carFormModel.photos!, (XFile file) async {
      var photo = await http.MultipartFile.fromPath("photos[]", file.path);
      photos.add(photo);
    });
  }

To explain: I looped through a list of Getx File (XFile) and I used fromPath constructor of http's MultipartFile class to populate my temporary empty list photos. What I did differently from the other answers is as a first parameter for the fromPath constructor, I used an array variable photos[ ] instead of just putting simple variable like photos. If it matters, my API is made with Laravel. Hope this helped✌

Comments

0

This is my solution:

Step: 01

/// getting file
  uiDocumentList = await _pickFilesWithSizeLimit();
  debugPrint("fileSize: ${uiDocumentList.map((e) => e.size)}");
  debugPrint(("fileName: ${uiDocumentList.map((e) => e.name)}"));
  debugPrint(("filePath: ${uiDocumentList.map((e) => e.path)}"));

Step:02

/// Storing MultipartFile in list
      List<MultipartFile> multipartFileList = [];
      for (int i = 0; i < uiDocumentList.length; i++) {
        debugPrint("isFile: ${uiDocumentList[i]}");
        /// Adding into list
        String filename = uiDocumentList[i].path!.split('/').last;
        multipartFileList.add(await MultipartFile.fromFile(
          uiDocumentList[i].path!,
          filename: filename,
        ));
      }

Step:03

  /// formData
  FormData formData = FormData.fromMap({
    "attachment_files": multipartFileList,
  });

Step 04:

 ///Make API Call
  if (multipartFileList.isNotEmpty) {
    debugPrint("beforeAPICall: $multipartFileList");

    /// Call Post API
    Response? response = await NewNetworkManager.instance.callPostAPI(
        url: uploadAttachmentFileApiUrl,
        myHeaders: header,
        body: formData //formData,
        );
    _logger.i("response: ${response!.data}");
  }

This is the function (_pickFilesWithSizeLimit) returning multiple files:

//Check Pick File Size and return list
  Future<List<PlatformFile>> _pickFilesWithSizeLimit() async {
    /// Result
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      allowMultiple: true,
      type: FileType.custom,
      allowedExtensions: [
        'gif',
        'indd',
        'ai',
        'psd',
        'svg',
        'txt',
        'csv',
        'jpeg',
        'docx',
        'xlsx',
        'pptx',
        'png',
        'jpg',
        'pdf',
        'doc',
        'zip'
      ],
    );


 if (result != null && result.files.isNotEmpty) {
      //
      List<PlatformFile> pickedFiles = result.files;
      List<PlatformFile> validFiles = [];

      //Check if file size less or greater
      for (var file in pickedFiles) {
        int maxSizeInBytes = 10 * 1024 * 1024; // 10MB
        if (file.size <= maxSizeInBytes) {
          validFiles.add(file);
        } else {
          Toasts.getWarningToast(text: "File size is not allowed");
        }
      }

      if (validFiles.isNotEmpty) {
        return validFiles;
      } else {
        Toasts.getWarningToast(text: "No files within size limit found.");
        throw Exception('No files within size limit found.');
      }
    } else {
      Toasts.getWarningToast(
          text: "File picking cancelled or no files selected.");
      throw Exception('File picking cancelled or no files selected.');
    }
  }

Comments

0

You can just use request.files.addAll here a example :

Future uploadMultipleImage(List images) async {


var uri = Uri.parse("");
  http.MultipartRequest request = new http.MultipartRequest('POST', uri);
  request.headers[''] = '';
  request.fields['user_id'] = '10';
  request.fields['post_details'] = 'dfsfdsfsd';
  //multipartFile = new http.MultipartFile("imagefile", stream, length, filename: basename(imageFile.path));
  List<MultipartFile> newList = new List<MultipartFile>();
  for (int i = 0; i < images.length; i++) {
    File imageFile = File(images[i].toString());
    var stream =
        new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
    var length = await imageFile.length();
    var multipartFile = new http.MultipartFile("imagefile", stream, length,
        filename: baseName(imageFile.path));
    newList.add(multiPartFile);
  }
  request.files.addAll(newList);
  var response = await request.send();
  if (response.statusCode == 200) {
    print("Image Uploaded");
  } else {
    print("Upload Failed");
  }
  response.stream.transform(utf8.decoder).listen((value) {
    print(value);
  });
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.