Flutter: How to send multiple images using for loop - flutter

I am using http package to perform multipart request.I am trying to upload multiple images using for loop but I am not getting any idea how to do it following is my postman response in the below image you can see 2 fields one is attribute and another one is image here I want to loop only adhar and pan inside attributes after sending "mobileno":"4567654","role":"p","userstatus":"D", to database
following is my multipart request code
Future<void> insertCategory(String category, BuildContext context) async {
var flutterFunctions =
Provider.of<FlutterFunctions>(context, listen: false);
var data = {"mobileno":"4567654","role":"p","userstatus":"D","adhar":"adhar","pan":"pan"};
var url = PurohitApi().baseUrl + PurohitApi().insertcategory;
Map<String, String> obj = {"attributes": json.encode(data).toString()};
try {
loading();
final client = RetryClient(
http.Client(),
retries: 4,
when: (reponse) {
return reponse.statusCode == 401 ? true : false;
},
onRetry: (request, response, retryCount) async {
if (retryCount == 0 && response?.statusCode == 401) {
var accesstoken = await Provider.of<Auth>(context, listen: false)
.restoreAccessToken();
request.headers['Authorization'] = accesstoken;
print(accesstoken);
}
},
);
var response = await http.MultipartRequest('Post', Uri.parse(url))
..files.add(await http.MultipartFile.fromPath(
"imagefile", flutterFunctions.imageFile!.path,
contentType: MediaType("image", "jpg")))
..headers['Authorization'] = token!
..fields.addAll(obj);
final send = await client.send(response);
final res = await http.Response.fromStream(send);
var messages = json.decode(res.body);
loading();
print(messages);
} catch (e) {
print(e);
}
}

Future<Object> addUserImages(List<XFile> files, String userID, String token) async {
try {
var url = Uri.parse(API_BASE_URL + addUserImagesUrl);
var request = http.MultipartRequest("POST", url);
request.headers['Authorization'] = "Bearer ${StaticServices.userBaseModel!.token!.token}";
for (var i = 0; i < files.length; i++) {
String fileName = DateTime.now().microsecondsSinceEpoch.toString().characters.takeLast(7).toString();
var pic = http.MultipartFile.fromBytes("files", await File(files[i].path).readAsBytes(), filename: '${userID}_${i}_$fileName', contentType: MediaType("image", files[i].mimeType ?? "png"));
//add multipart to request
request.files.add(pic);
}
var response = await request.send();
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
if (response.statusCode == 200) {
return Success(response: Images.fromJson(jsonDecode(responseString)));
}
return Failure(
errorMessage: responseString,
);
} on HttpException {
return Failure(errorMessage: "No Internet Connection");
} on FormatException {
return Failure(errorMessage: "Invalid Format");
} on SocketException {
return Failure(errorMessage: "No Internet Connection");
} catch (e) {
return Failure(errorMessage: "Invalid Error");
}
}

Related

Http listening to upload progress Flutter Web

I was trying to listen to the upload progress using StreamedRequest and wanted to show the upload progress in UI by listening to bytes sent, but for some reason, it doesn't seem to work. The file is being picked with the file picker package and the selected file is in binary format (Unit8List). Here's the code:
final sha1OfFileData = sha1.convert(fileData);
try {
final request = http.StreamedRequest('POST', Uri.parse(data['uploadUrl']));
request.headers.addAll({
'Authorization': data['authorizationToken'],
'Content-Type': "application/octet-stream",
'X-Bz-File-Name': fileName,
'X-Bz-Content-Sha1': sha1OfFileData.toString(),
'X-Bz-Server-Side-Encryption': 'AES256',
});
request.sink.add(fileData);
final streamedResponse = await request.send();
var received = 0;
var total = streamedResponse.contentLength ?? -1;
streamedResponse.stream.listen(
(List<int> chunk) {
received += chunk.length;
if (total == -1) {
print('Received $received bytes');
} else {
final progress = received / total;
print('Upload progress: ${(progress * 100).toStringAsFixed(2)}%');
}
},
onDone: () async {
final responseBytes = await streamedResponse.stream.toBytes();
final responseString = utf8.decode(responseBytes);
response = jsonDecode(responseString);
print(response);
},
onError: (error) {
print('Error uploading file: $error');
},
cancelOnError: true,
);
} catch (e) {
print(e);
}
However if I upload it with the normal request, it works, here's that code:
final sha1OfFileData = sha1.convert(fileData);
var response;
try {
final request = http.Request('POST', Uri.parse(data['uploadUrl']));
request.headers.addAll({
'Authorization': data['authorizationToken'],
'Content-Type': "application/octet-stream",
'X-Bz-File-Name': fileName,
'X-Bz-Content-Sha1': sha1OfFileData.toString(),
'X-Bz-Server-Side-Encryption': 'AES256',
});
request.bodyBytes = fileData;
final streamedResponse = await request.send();
final responseBytes = await streamedResponse.stream.toBytes();
final responseString = utf8.decode(responseBytes);
response = jsonDecode(responseString);
print(response);
} catch (e) {
print(e);
}

cannot able to send files with extact format in flutter

I'm currently working in a flutter, I'm trying to send a file to the backend server. But I can send a file but the extension is showing as BIN and the file is not supported.
pick() async {
var img = await ImagePicker().getImage(source: ImageSource.gallery);
image = img;
}
send() async {
// if (imageFile == null) {
// return Get.snackbar("alert", 'Please select image');
// }
try {
String? message = messageController.text;
final url = Uri.parse('http://localhost:8000/integration-test');
//Map<String, String> headers = {'Authorization': 'Bearer $token'};
Uint8List data = await this.image.readAsBytes();
List<int> list = data.cast();
var request = http.MultipartRequest('POST', url)
//..headers.addAll(headers)
..fields['sender'] = "venkat"
..fields['numbers'] = numbers
..fields['message'] = message;
if (image != null) {
request.files.add(http.MultipartFile.fromBytes('file', list,
filename: 'example.jpeg'));
}
var response = await request.send();
//var decoded = await response.stream.bytesToString().then(json.decode);
if (response.statusCode == 200) {
Get.snackbar("alert", 'SUCESS');
} else {
Get.snackbar("alert", 'FAILED');
}
} catch (e) {
Get.snackbar('alert', 'Image failed: $e');
}
}
and help to set the file name dynamically.
when i done it with ajax and jquery it works file i need the exact result like this
let formData = new FormData();
let file = $('#1file')[0].files[0];
const sender=c;
const message = $('.i-message').val();
const datepick=$("#i-datetimepicker").val();
formData.append('sender',c);
formData.append('numbers',JSON.stringify(irecepient));
formData.append('message',message);
if(file){
formData.append('file',file);
}
if(datepick){
formData.append('date',datepick);
}
$.ajax({
type: "POST",
url: "http://localhost:8000/integration-test",
//enctype: 'multipart/form-data',
contentType:false,
processData:false,
data: formData,
success: function (data) {
if(data !=0){
$('.logs').append($('<li>').text("task processing"));
}else{
$('.logs').append($('<li>').text("task failed"));
}
}
});
});
this works good and i expect the above flutter code to do this

Image not uploading in DIO 4 and above

Greeting everyone, my image is not uploading to my server when i update to DIO 4.0.0 and above. The same code works for DIO version below 4.0.0 . Below is the upload code. Kindly help me out. Thanks
Future<dynamic> upload(String url, BuildContext context,
{List<File> files,
Map body,
FileCount count = FileCount.MULTIPLE,
authorize = true}) async {
BaseOptions options = await getOptions(validate: authorize);
dynamic response, serverResponse;
List<MultipartFile> uploadFiles = [];
FormData requestData;
try {
Dio dio = new Dio(options)..interceptors.add(Logging());
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(client) {
SecurityContext sc = new SecurityContext();
HttpClient httpClient = new HttpClient(context: sc);
//allow all cert
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
return httpClient;
};
// add files to uploadFiles array
if (files.length > 0) {
for (var index = 0; index < files.length; index++) {
MultipartFile file = MultipartFile.fromFileSync(files[index].path,
filename: basename(files[index].path),contentType:MediaType.parse('image/jpg'));
uploadFiles.add(file);
}
print("file the request: $uploadFiles");
requestData = FormData.fromMap({"file": uploadFiles});
} else {
requestData = FormData();
}
body.forEach((key, value) {
MapEntry<String, String> data = new MapEntry(key, '$value');
requestData.fields.add(data);
});
print("sending the request: ${uploadFiles.asMap().values}");
serverResponse = await dio.post(
url,
data: requestData,
options: new Options(contentType: 'multipart/form-data'),
onSendProgress: (int sent, int total) {
print('$sent $total');
},
);
print("Server Replied: $serverResponse}");
print(serverResponse.data);
//check for connection errors
if (serverResponse.statusCode < 200 || serverResponse.statusCode > 400) {
return _decoder.convert(
'{"success":false,"message":"${LocalText.of(context).load("error_executing_request")}"}');
}
response = _decoder.convert(serverResponse.data);
print("Response: $response");
} on DioError catch (e) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx and is also not 304.
if (e.response != null) {
print(e.response.data);
print(e.response.headers);
// print(e.response.request);
response = _decoder.convert(
'{"success":false,"message":"${LocalText.of(context).load("server_error")}"}');
} else {
// Something happened in setting up or sending the request that triggered an Error
print(e.message);
response =
_decoder.convert('{"success":false,"message":"' + e.message + '"}');
}
} catch (error) {
return _decoder.convert(
'{"success":false,"message":"${LocalText.of(context).load("error_executing_request")}"}');
}
return response;
}

http MultipartRequest file not receiving in server

I'm trying to upload image to my server but it's not receiving in my server when I upload file from app. But if I upload via postman it works but not from simulator
My Code
final request = http.MultipartRequest(
'POST', Uri.parse(''));
request.fields['title'] = title.text;
request.fields['sub_title'] = subTitle.text;
request.files
.add(await http.MultipartFile.fromPath('profile_photo', photo.path));
request.files
.add(await http.MultipartFile.fromPath('profile_video', video.path));
var response = await request.send();
var responseString = await response.stream.bytesToString();
print(responseString);
`
Output
{'title': 'zia', 'sub_title' : 'sultan', 'profile_photo' : {}, 'profile_video' : {}}
I too faced a similar issue and here is the solution to how I fixed it:
var fileExtension = AppUtils.getFileExtension(filePath);
if (fileExtension.isEmpty) {
AppUtils.showToast('File extension was not found');
return false;
}
final file = await http.MultipartFile.fromPath('vid', filePath,
contentType: MediaType('application', fileExtension));
request.files.add(file);
var res = await request.send();
if (res.statusCode == 200) {
final respString = await res.stream.bytesToString();
debugPrint('respString: $respString');
}
AppUtils:
class AppUtils {
static String getFileExtension(String filePath) {
try {
int index = filePath.lastIndexOf('.');
return filePath.substring(index + 1);
} catch (e) {
return '';
}
}
}

CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate in MultipartFile

HandshakeException: Handshake error in client (OS Error:
CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate(handshake.cc:354))
getting HandshakeException while upload file and fields
const TestMode = true;
addAssets(Map formFields, List files) async {
Map resp = {
'Status' : false,
'Msg' : "Unable to add asset"
};
try {
Uri url = Uri.parse("$BaseUrl$AddAssetUrl");
http.MultipartRequest multi = http.MultipartRequest("POST", url);
formFields.forEach((key, val) {
multi.fields[key] = val;
});
for (var val in files) {
var myFile = await http.MultipartFile.fromPath('MediaFiles[]', val);
multi.files.add(
myFile,
);
}
http.StreamedResponse streamedResponse = await multi.send().then((response) async {
return response;
});
String body = await streamedResponse.stream.bytesToString();
if(streamedResponse.statusCode == 200 && isJSON(body)){
Map data = json.decode(body);
resp['Status'] = data['Status'];
resp['Msg'] = data['Msg'];
}
debugPrint(body);
} catch (e) {
if(TestMode) print(e.toString());
}
return resp;
}
Upload file using MultipartFile
TestMode is constant
http is alias of package:http/http.
Reference: Github
Just send your request via IOClient
example:
addAssets(Map formFields, List files) async {
Map resp = {
'Status' : false,
'Msg' : "Unable to add asset"
};
try {
Uri url = Uri.parse("$BaseUrl$AddAssetUrl");
http.MultipartRequest multi = http.MultipartRequest("POST", url);
formFields.forEach((key, val) {
multi.fields[key] = val;
});
for (var val in files) {
var myFile = await http.MultipartFile.fromPath('MediaFiles[]', val);
multi.files.add(
myFile,
);
}
HttpClient httpClient = HttpClient();
httpClient .badCertificateCallback = (X509Certificate cert,String host,int port) {
return getBaseUrl() == host;
};
http.StreamedResponse streamedResponse = await IOClient(
httpClient
).send(multi);
String body = await streamedResponse.stream.bytesToString();
if(streamedResponse.statusCode == 200 && isJSON(body)){
Map data = json.decode(body);
resp['Status'] = data['Status'];
resp['Msg'] = data['Msg'];
}
debugPrint(body);
} catch (e) {
if(TestMode) print(e.toString());
}
return resp;
}
String getBaseUrl(){
String url = 'https://hostname.com/api_dir/'; // Your api url
url = url.substring(url.indexOf('://')+3);
return url.substring(0,url.indexOf('/'));
}