How to parse a binary data collection (list of files) from multipart/form-data http response? - flutter

How to parse a multipart/form-data of http response from server, if it contains a list of binary files (images)?
For example:
var request = http.MultipartRequest('GET', url);
var streamedResponse = await request.send();
if (streamedResponse.statusCode == 200) {
var response = await http.Response.fromStream(streamedResponse); // it is just a binary data, not a list of files
}
Maybe there is something similar to HttpMultipartParser from .NET in flutter?

Try below solution
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);
});
}

Related

I'm using flutter to update user in Strapi. While running the following code, I am only able to change other fields details but not image. Thank you

I am trying to do so using Multipartfile class. My field name in the strapi is profile_image. Other details are updated, but neither image is uploaded in the media library, nor image is updated for this particular record.
try {
var url = "${kAPIURL}users/${bodyData["id"]}";
var imageBytes = await image!.readAsBytes();
int length = imageBytes.length;
http.ByteStream byteStream = http.ByteStream(image.openRead());
Stream<List<int>> stream = byteStream.cast();
var request = http.MultipartRequest('PUT', Uri.parse(url));
request.headers['Authorization'] = 'Bearer ${bodyData["jwt"]}';
request.fields['id'] = bodyData['id'];
request.fields['username'] = bodyData['username'];
request.fields['specific_type'] = bodyData['specific_type'];
request.fields['sex'] = bodyData['sex'];
request.fields['phone_number'] = bodyData['phone_number'];
request.fields['email'] = bodyData['email'];
var profileImage = http.MultipartFile(
'files.profile_image', stream, length,
filename: image.path.split('/').last.toString(),
contentType: MediaType('image', 'jpg'));
request.files.add(profileImage);
var response = await request.send();
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
if (response.statusCode == 200) {
Provider.of<MainScreenProvider>(context, listen: false).isDeleteCache =
true;
return response;
} else {
return response;
}
} on Exception {
throw Exception("Unable to update user details.");
}

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 '';
}
}
}

Invalid request payload input on flutter post request

I am trying to uploading multiple files from my flutter mobile app. Here is my screenshot of the postman. This works fine on postMan. But I am getting 400 errors on the flutter mobile app. I can't find out where is the problem?
Now here is the code of my flutter mobile app upload.
if(images.length>0){
for (int i = 0; i < images.length; i++) {
var path = await FlutterAbsolutePath.getAbsolutePath(images[i].identifier);
String fileName = path.split('/').last;
var file = await MultipartFile.fromFile(path, filename:fileName);
multipart.add(file);
}
FormData imageFormData = FormData.fromMap(
{
"feedId": value.id,
"images": multipart,
"userInformationsId": value.userInformationId
});
print(multipart.length);
uploadFeedPicture(imageFormData);
}
Future<String> uploadFeedPicture(FormData _imageformData) async{
String at = await _apiProvider.getAccessToken();
Dio dio = new Dio();
// dio.options.headers['accept'] = 'application/json';
// dio.options.headers["content-Type"] = "multipart/form-data";
dio.options.headers["Authorization"] = "Bearer ${at}";
dio.options.baseUrl = getBaseUrl();
var _baseUrl = getBaseUrl();
await dio.post('/api/feed/upload', data: _imageformData, options: Options(
followRedirects: false,
validateStatus: (status) { return status < 500; }
), onSendProgress: (int sent, int total) {
print("$sent $total");
},).then((value) {
print(value.data);
print(value.headers);
}
).catchError((error) => print(error) );
}
And I am getting this response.
{statusCode: 400, error: Bad Request, message: Invalid request payload input}
Please Help me out where is the problem? I try with change content-type but not working.
After trying so many different ways I found the solution. Here it is.
if(value.id != null){
String at = await _apiProvider.getAccessToken();
Map<String, String> headers = { "Authorization": "Bearer ${at}"};
var uri = Uri.parse('$baseUrl/api/feed/upload');
var request = http.MultipartRequest('POST', uri);
request.headers.addAll(headers);
if(images.length>0){
for (int i = 0; i < images.length; i++) {
var path = await FlutterAbsolutePath.getAbsolutePath(images[i].identifier);
// String fileName = path.split('/').last;
var file = await MultipartFile.fromPath("images",path);
request.files.add(file);
}
request..fields['feedId'] = value.id;
request..fields['userInformationsId'] = value.userInformationId;
var response = await request.send();
if (response.statusCode == 200) {
Navigator.pop(context);
showSuccessToast("Posted succesfull");
counter.update(0);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
}else{
showErrorToast("Upload image failed");
}
}
}

How do I upload image in Flutter App to my server and decode the json response from the server?

I have an Endpoint on my server which accepts multipart/form-data and sends back json as a response.
I want to send an Image from my flutter App to my server and Decode the json received from the server.
You can use http.MultipartRequest for that
Example:-
static Future<UploadImageRes> uploadImage(int id, File imageFile) async {
if (imageFile != null) {
var stream = new http.ByteStream(imageFile.openRead());
var length = await imageFile.length();
String token = PreferenceUtils.getString(AppConstants.LOGGED_IN);
var uri = Uri.parse(UrlConstants.ADD_RECIPE_PHOTO);
LogUtils.d("====uri : $uri");
LogUtils.d("====recipeId : $id");
var request = new http.MultipartRequest("POST", uri);
String fileName = imageFile.path.split("/").last;
var multipartFile = new http.MultipartFile('photo', stream, length,
filename: fileName, contentType: new MediaType('image', 'jpeg'));
request.headers.addAll({"Authorization": "Bearer $token"});
request.files.add(multipartFile);
request.fields["recipeId"] = "$id";
var response = await request.send();
var statusCode = response.statusCode;
LogUtils.d("====statusCode : $statusCode");
if (statusCode < 200 || statusCode >= 400) {
throw new ApiException("Uploading failed");
}
final respStr = await response.stream.bytesToString();
return Future.value(UploadImageRes.fromJson(JsonDecoder().convert(respStr)));
} else {
throw new ApiException("Uploading failed");
}
}
In final respStr = await response.stream.bytesToString(); you will get your api response

how to upload image to rest API in flutter through http post method?

I'm trying to upload an image through the flutter via post method. and I'm using image_picker for pick file from mobile but I can't able to upload
and I have tried to send the file like FormData that also doesn't work
Future<dynamic> uploadLicence(int id ,dynamic obj) async {
FormData formdata = new FormData(); // just like JS
formdata.add("image",obj);
final response = await post('Logistic/driver/LicenceImage?
driverId=$id',
formdata);
print(response);
// return null;
if (response.statusCode == 200) {
final result = json.decode(response.body);
return result;
} else {
return null;
}
}
after that, I just tried with this method but this also not working
Future<dynamic> uploadLicence(int id, File file) async {
final url = Uri.parse('$BASE_URL/Logistic/driver/LicenceImage?
driverId=$id');
final fileName = path.basename(file.path);
final bytes = await compute(compress, file.readAsBytesSync());
var request = http.MultipartRequest('POST', url)
..files.add(new http.MultipartFile.fromBytes(
'image',bytes,filename: fileName,);
var response = await request.send();
var decoded = await
response.stream.bytesToString().then(json.decode);
if (response.statusCode == HttpStatus.OK) {
print("image uploded $decoded");
} else {
print("image uplod failed ");
}
}
List<int> compress(List<int> bytes) {
var image = img.decodeImage(bytes);
var resize = img.copyResize(image);
return img.encodePng(resize, level: 1);
}
It's possible with MultipartRequest. Or you can use simply dio package. It's one command.
With http:
import 'package:http/http.dart' as http;
final Uri uri = Uri.parse(url);
final http.MultipartRequest request = http.MultipartRequest("POST", uri);
// Additional key-values here
request.fields['sample'] = variable;
// Adding the file, field is the key for file and file is the value
request.files.add(http.MultipartFile.fromBytes(
field, await file.readAsBytes(), filename: filename);
// progress track of uploading process
final http.StreamedResponse response = await request.send();
print('statusCode => ${response.statusCode}');
// checking response data
Map<String, dynamic> data;
await for (String s in response.stream.transform(utf8.decoder)) {
data = jsonDecode(s);
print('data: $data');
}
I user this code for my project i hope work for you
Upload(File imageFile) async {
var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
var uri = Uri.parse(uploadURL);
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile('file', stream, length,
filename: basename(imageFile.path));
//contentType: new MediaType('image', 'png'));
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}