Issues sending multiple images on Flutter using Multipart and Dio - flutter

I'm trying to send multiple files that came from Multi Image Picker pluggin on Flutter to my server, for this I'm trying to use Dio to send it. But the Multipart tag isn't uploading the files too. How to proceed?
Future<Response> _uploadFile() async {
var catUpload = jsonEncode(incluirCategoriasParaUpload());
final FormData formData = FormData.fromMap({
"action": 'add_Anuncio',
"filial_id": "1",
"titulo": tituloControler.text,
"descricao": descricaoControler.text,
"categorias": catUpload
});
for (var val in listaImagensParaUpload) {
ByteData byteData = await val.getByteData();
Uint8List pngBytes = byteData.buffer.asUint8List();
formData.files.add(
MapEntry("arquivos",
await MultipartFile.fromBytes(pngBytes, filename: "teste")
)
);
}
Dio dio = new Dio();
dio.interceptors.add(alice.getDioInterceptor());
return await dio
.post(URL_WS + WS_PAGE,
data: formData,
options: Options(method: 'POST', responseType: ResponseType.json))
.timeout(Duration(seconds: 2000));
// .catchError(dioError);
}

You must declare as toList() this for loop.
Here is an example how to make it.
formData = FormData.fromMap({
'id': '1',
'title': 'myTitle',
'files': [
for (var file in listFiles)
{await MultipartFile.fromFile(item.path, filename: 'fileName')}
.toList()
]
});
I am usign Dio library working with MultiPartFile.

I am posting this solution with dio and image_picker dependency. And it will definitely work. I have spent 2 days for this solution.
FormData formData = new FormData.fromMap({
"name": "Max",
"location": "Paris",
"age": 21,
"image[]": [
await MultipartFile.fromFile(
_imageFile.path,
),
await MultipartFile.fromFile(
_imageFile.path,
),
],
});
print(FormData1().then((value) {
print(value);
}));
response = await dio.post(
"http://143.110.244.110/radius/frontuser/eventsubmitbutton",
data: formData,
onSendProgress: (received, total) {
if (total != -1) {
print((received / total * 100).toStringAsFixed(0) + '%');
}
},
);
print(response);

Related

Flutter - How to send multiple images in formdata

I want to upload multiple images in flutter using dio and formData. What I did is I created a for loop for storing MultipartFile in an array and then I passed the array to the data of "img[]". However, I cannot upload the image if I passed the array but it works perfectly fine if I upload a single image.
Here's my code.
var arr = new List(3);
for (var i=0; i <_tryPath.length; i++) {
arr[i] = await MultipartFile.fromFile(imageFile[i].path, filename:
imageFile[i].path.split('/').last, contentType: new MediaType('image','jpg'));
};
print('this is arr = $arr');
FormData formData = new FormData.fromMap({
"name": "Max",
"location": "Paris",
"age": 21,
"img[]": arr,
});
// dio is in another class here in AuthService.
AuthService().donateRegister(formData).then((val) async {
print('successful');
print(val.data);
});
Can you help me uploading many images in formData? I also would like not to limit the MediaType. What will I do if I will also upload pdf/docu or jpg MediaType? I will appreciate your time and answer. Thank you!
You can use a for loop to set image lists as show below
here I'm using multi_image_picker
Future<int> addMultiImage({MyData myData, List<Asset> files}) async {
var formData = FormData.fromMap({
"name": "Max",
"location": "Paris",
"age": 21,
});
for (int i = 0; i < files.length; i++) {
var path = await FlutterAbsolutePath.getAbsolutePath(files[i].identifier);
formData.files.addAll([
MapEntry("img", await MultipartFile.fromFile(path, filename: path))
]);
}
Response response = await dioHelper.post(
"myPaths",
queryParameters: {
},
data: formData,
);
You can use mime package to get mime type.
import 'package:path/path.dart' as path;
import 'package:mime/mime.dart';
String getFileName(String _path){
return path.basename(_path)
}
FilePickerResult? result = await FilePicker.platform.pickFiles(
allowMultiple: true,
type: FileType.custom,
allowedExtensions: ['jpg', 'pdf', 'doc'],
);
if(result != null) {
List<MultipartFile> files = result.paths.map((path) =>
MultipartFile.fromFileSync(
path,
filename: getFileName(path),
contentType: MediaType(
lookupMimeType(getFileName(path)).split('/')[0],
lookupMimeType(getFileName(path)).split('/')[1],
),
)
).toList();
var dio = Dio();
var formData = FormData.fromMap({
'name': 'wendux', // other parameter may you need to send
'age': 25, // other parameter may you need to send
'files': files,
});
var response = await dio.post('url', data: formData);
// check response status code
if(response.statusCode == 200){
// it's uploaded
}
} else {
// User canceled the picker
}

Upload images list with dio

I've use this code in my application with Dio: 2.2.2 and it works fine, but after upgrading my Dio package version, I must use the MultipartFile option. I tried to use it, but all data sent ok without the images. How can I upgrade this code to use with the latest Dio package version?
Old code:
Future add(name,desc,address,images) async {
Map ad_data;
await dio
.post("${host}/add",
data: FormData.from({
"name": "${name}",
"desc": "${desc}",
"address": "${address}",
"image[]": images
.map((image) =>
UploadFileInfo(File(image.path), basename(image.path)))
.toList(),
}),).then((data) {
ad_data = data.data;
});
return ad_data;
}
Update your add function with the below one... I am using dio: ^4.0.0.
import 'package:path/path.dart';
Future add(name,desc,address,images) async {
var formData = FormData.fromMap({
'name': name,
'desc': desc,
'address': address,
'files': [
for (var item in images)
{
await MultipartFile.fromFile(item.path,
filename: basename(item.path))
}.toList()
],
});
await dio.post("${host}/add",data:formData).then((data) {
ad_data = data.data;
});
return ad_data;
}
I have a costum function for uploading one file, you can change it and use.
Dio getBaseDio() {
var token = "AccessToken";
Dio dio = Dio(BaseOptions(
baseUrl: "your base url",
headers: {
"Authorization": "Bearer $token",
"Accept": "application/json",
}));
return dio;
}
after this :
Future<Response> postWithFile(
String url,
dynamic body) async {
return await getBaseDio().post(url, data: body)
.catchError(
(error) {
return error.response;
},
);
}
now you can use postWithFile function like this:
FormData formData = FormData.fromMap({
"param1": "value1",
"param2": "value2,
"fileParam": await MultipartFile.fromFile(attachPath, filename: fileName),
});
var result = await postWithFile(url, formData);
I hope I was able to help.
add content type
contentType: MediaType(
"image", "${item.path.split(".").last}"),

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 ?
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
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);

How to upload multiple images/files in Flutter using Dio?

I have been trying to upload multiple images/files to the backend in Flutter. I am using Dio.
So far, I have not been able to do so.
I have been able to do so using postman. This is the form-data
This is my code:
Future<dynamic> fileUpload(List<String> filepath, String url) async {
var token = await storage.getToken();
var idToken = await storage.getIdToken();
Dio dio = Dio();
List uploadList = [];
for (var file in filepath) {
var multipartFile = await MultipartFile.fromFile(
file
);
uploadList.add(multipartFile);
}
FormData formData = FormData.fromMap({"assignment": uploadList});
var response = await dio.post(APIURL.baseUrl + url,
data: formData,
options: Options(headers: {
HttpHeaders.authorizationHeader: "Bearer $token",
'idToken': idToken,
}));
return response;
}
Can somebody please help.
Turns out there are two ways to add multiple files to FormData. The following approach worked
var formData = FormData();
for (var file in filepath) {
formData.files.addAll([
MapEntry("assignment", await MultipartFile.fromFile(file)),
]);
}
final httpDio = Dio();
final formData = dio.FormData.fromMap({
"data": "{}",
"File": await dio.MultipartFile.fromFile(
filePath,
filename: filePath.toString().split("/").last,
contentType: MediaType('image', 'jpg'),
),
"type": "image/jpg"
});
final dio.Response response = await httpDio.post(
Strings.baseUrl +"/"+ Strings.documentUpload,
data: formData,
options: dio.Options(
headers: {
"RequestVerificationToken": box.read(Keys.token),
"Content-Type": "multipart/form-data"
}
)
);
This works as well:
var formData = FormData();
for (var file in filepath) {
formData.files.add(MapEntry("assignment",
MultipartFile.fromFileSync(file)));
}

Erro 502 with dio [duplicate]

This question already has answers here:
How to upload images to server in Flutter?
(15 answers)
Closed 3 years ago.
How to make upload the image with dio in flutter?
void _postHttp() async {
try {
Dio dio = Dio();
dio.options.contentType = Headers.formUrlEncodedContentType;
FormData formData = new FormData.fromMap({
"file": await MultipartFile.fromFile("/Users/rogerio/Downloads/tshirt_view_kovi.jpg",
filename: "tshirt_view_kovi.jpg"),
"type": "checklist",
"source": "0bef60ed-f538-4a35-b5ef-70f7dfaf510e"
});
Response response = await dio.post(
"https://api.kovi.dev/docs/upload-generic",
data: formData,
options: Options(contentType: Headers.jsonContentType));
print(response);
} catch (e) {
print(e);
}
}
My code return error 502
Why do you set contentType to json? it should be multipart: multipart/form-data. Try this snippet without any options:
final dio = Dio();
final formData = FormData.fromMap({
"file": await MultipartFile.fromFile(
"/Users/rogerio/Downloads/tshirt_view_kovi.jpg",
filename: "tshirt_view_kovi.jpg",
),
"type": "checklist",
"source": "0bef60ed-f538-4a35-b5ef-70f7dfaf510e"
});
final response = await dio.post(
"https://api.kovi.dev/docs/upload-generic",
data: formData
);