Andreas Hunter
Andreas Hunter

Reputation: 5014

Flutter Dio add MultipartFile object to Map dynamicaly

I have custom data:

File avatar = File('path/to/file');

Map<String, dynamic> data = {
  'name': 'John',
  'avatar': avatar
}

How I can send this my data as FormData object to server?

I tried create object of MultipartFile class by looping my data but in my case sending file path as string instance of file. Here is my code:

data.forEach((key, value) {
  if (value is File) {
    String fileName = value.path.split('/').last;
    data.update(key, (value) async {
      return await MultipartFile.fromFile(value.path, filename: fileName);
    });
  }
});

FormData formData = FormData.fromMap(data);
var response = await dio.post("/send", data: formData);

But using Dio I can upload file something like this:

FormData formData = FormData.fromMap({
    "name": "wendux",
    "age": 25,
    "file": await MultipartFile.fromFile(file.path,filename: fileName)
});

Why I can't dynamically add MultipartFile to my Map ?

Upvotes: 0

Views: 4868

Answers (2)

Muhammad Tameem Rafay
Muhammad Tameem Rafay

Reputation: 4575

You can send it without dio. Here I write the whole code including the libraries and response.Please test the below code becuase in my case dio is not working and your case is very similar to my case.

Just send it with simple http request

import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:mime/mime.dart';

   Map<String, String> headers = {
      'Content-Type': 'multipart/form-data',        
    };

    Map jsonMap = {
      "name": "wendux",
      "age": 25,          
    };
 String imagePath, // add the image path in varible 

 var request = http.MultipartRequest('POST', Uri.parse(url));
    request.headers.addAll(headers);
    request.files.add(
      http.MultipartFile.fromBytes(
        'orderStatusUpdate',
        utf8.encode(json.encode(jsonMap)),
        contentType: MediaType(
          'application',
          'json',
          {'charset': 'utf-8'},
        ),
      ),
    );

    if (imagePath != null) {
      final mimeTypeData = lookupMimeType(imagePath).split('/');
      final file = await http.MultipartFile.fromPath('images', imagePath,
          contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
      print((mimeTypeData[0].toString())); // tells picture or not
      print((mimeTypeData[1].toString())); // return extention
      request.files.add(file);
    }

    http.StreamedResponse streamedResponse = await request.send();
    var response = await http.Response.fromStream(streamedResponse);
    print(response.statusCode);
    print(response.body);

Upvotes: 1

Adelina
Adelina

Reputation: 11881

You are not awaiting for your data

await Future.wait(data.map((k, v){
if(v is File){
v = await MultipartFile.fromFile(value.path, filename: fileName);
}
  return MapEntry(k, v);
}));

Please look into My async call is returning before list is populated in forEach loop

Upvotes: 1

Related Questions