How to upload multiple Images through Api - flutter

I am trying to Upload Multiple Images through Api but i am not understanding how to send a list, I can upload a single image though. Tried alot of searches but does'nt helped, i also import multi_image_picker i can pick the images but the problem is in uploading.
Future<Map<String, dynamic>> _uploadImage(File image) async {
String value = '';
SharedPreferences pref2 = await SharedPreferences.getInstance();
value = pref2.getString("user_role");
final mimeTypeData =
lookupMimeType(image.path, headerBytes: [0xFF, 0xD8]).split('/');
// Intilize the multipart request
final imageUploadRequest = http.MultipartRequest('POST', apiUrl);
// Attach the file in the request
final file = await http.MultipartFile.fromPath('photo', image.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
// Explicitly pass the extension of the image with request body
// Since image_picker has some bugs due which it mixes up
// image extension with file name like this filenamejpge
// Which creates some problem at the server side to manage
// or verify the file extension
imageUploadRequest.files.add(file);
imageUploadRequest.fields['mobile'] = _mobileNo.text;
imageUploadRequest.headers.addAll({
'Content-Type': 'application/json',
'Authorization': Constants.authToken,
});
var response = await imageUploadRequest.send();
if (response.statusCode == 200) print('Done!');
final respStr = await response.stream.bytesToString();
return json.decode(respStr);
}

this an example of uploading files to your API with HTTP package
import 'package:http/http.dart' as http;
void uploadFiles(List<File> files) async {
final url = YOUR-API-LINK;
for (var file in files) {
// Create a multipart request
var request = http.MultipartRequest('POST', Uri.parse(url));
// Add the file to the request
request.files.add(http.MultipartFile.fromBytes(
'file',
file.readAsBytesSync(),
filename: file.path.split('/').last,
));
// Send the request
var response = await request.send();
// Check the status code
if (response.statusCode != 200) {
print('Failed to upload file');
}else{
print response.body;
}
}
}
for Dio use this
void uploadFiles(List<File> files) async {
final url = YOUR-API-LINK;
// Create a Dio client
var dio = Dio();
// Create a FormData object
var formData = FormData();
// Add the files to the FormData object
for (var file in files) {
formData.files.add(MapEntry(
'file',
await MultipartFile.fromFile(file.path, filename: file.path.split('/').last),
));
}
// Send the request
var response = await dio.post(url, data: formData);
// Check the status code
if (response.statusCode != 200) {
print('Failed to upload files');
}else {
print(response.data)
}
}
as you can see there not much difference between them in http you use MultipartRequest in dio you use FormData.

Related

how to send a File to an REST api [duplicate]

I use a web service for image processing , it works well in Postman:
Now I want to make http request in flutter with Dart:
import 'package:http/http.dart' as http;
static ocr(File image) async {
var url = '${API_URL}ocr';
var bytes = image.readAsBytesSync();
var response = await http.post(
url,
headers:{ "Content-Type":"multipart/form-data" } ,
body: { "lang":"fas" , "image":bytes},
encoding: Encoding.getByName("utf-8")
);
return response.body;
}
but I don't know how to upload the image file, in above code I get exception: Bad state: Cannot set the body fields of a Request with content-type "multipart/form-data".
How should I write the body of request?
Your workaround should work; many servers will accept application/x-www-form-urlencoded as an alternative (although data is encoded moderately inefficiently).
However, it is possible to use dart:http to do this. Instead of using http.post, you'll want to use a http.MultipartFile object.
From the dart documentation:
var request = new http.MultipartRequest("POST", url);
request.fields['user'] = 'someone#somewhere.com';
request.files.add(http.MultipartFile.fromPath(
'package',
'build/package.tar.gz',
contentType: new MediaType('application', 'x-tar'),
));
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
I'd like to recommend dio package to you , dio is a powerful Http client for Dart/Flutter, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.
dio is very easy to use, in this case you can:
Sending FormData:
FormData formData = new FormData.from({
"name": "wendux",
"file1": new UploadFileInfo(new File("./upload.jpg"), "upload1.jpg")
});
response = await dio.post("/info", data: formData)
More details please refer to dio。
This can be achieved using the MultipartRequest class (https://pub.dev/documentation/http/latest/http/MultipartRequest-class.html)
Change the media type and uri as needed.
uploadFile() async {
var postUri = Uri.parse("<APIUrl>");
var request = new http.MultipartRequest("POST", postUri);
request.fields['user'] = 'blah';
request.files.add(new http.MultipartFile.fromBytes('file', await File.fromUri("<path/to/file>").readAsBytes(), contentType: new MediaType('image', 'jpeg')))
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
}
I found a working example without using any external plugin , this only uses
import 'package:http/http.dart' as http;
import 'dart:io';
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:convert';
Code
var stream =
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
// get file length
var length = await imageFile.length(); //imageFile is your image file
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": "Bearer " + token
}; // ignore this headers if there is no authentication
// string to uri
var uri = Uri.parse(Constants.BASE_URL + "api endpoint here");
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// multipart that takes file
var multipartFileSign = new http.MultipartFile('profile_pic', stream, length,
filename: basename(imageFile.path));
// add file to multipart
request.files.add(multipartFileSign);
//add headers
request.headers.addAll(headers);
//adding params
request.fields['loginId'] = '12';
request.fields['firstName'] = 'abc';
// request.fields['lastName'] = 'efg';
// send
var response = await request.send();
print(response.statusCode);
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
How to upload image file using restAPI in flutter/dart.
This work for me.
var postUri = Uri.parse("apiUrl");
http.MultipartRequest request = new http.MultipartRequest("POST", postUri);
http.MultipartFile multipartFile = await http.MultipartFile.fromPath(
'file', filePath);
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
print(response.statusCode);
Updated 2021 way:
using flutter http and mime
import 'package:mime/mime.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'dart:io';
Future<dynamic> multipartImageUpload(String baseUrl, String api, File image) async {
var uri = Uri.parse(baseUrl + api);
final mimeTypeData =
lookupMimeType(image.path, headerBytes: [0xFF, 0xD8]).split('/');
// Intilize the multipart request
final imageUploadRequest = http.MultipartRequest('PUT', uri);
// Attach the file in the request
final file = await http.MultipartFile.fromPath('image', image.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
imageUploadRequest.files.add(file);
// add headers if needed
//imageUploadRequest.headers.addAll(<some-headers>);
try {
final streamedResponse = await imageUploadRequest.send();
final response = await http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
print(e);
return null;
}
}
Use MultipartRequest class.
How to upload image file using restAPI in flutter/dart
void uploadImage1(File _image) async {
// open a byteStream
var stream = new http.ByteStream(DelegatingStream.typed(_image.openRead()));
// get file length
var length = await _image.length();
// string to uri
var uri = Uri.parse("enter here upload URL");
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// if you need more parameters to parse, add those like this. i added "user_id". here this "user_id" is a key of the API request
request.fields["user_id"] = "text";
// multipart that takes file.. here this "image_file" is a key of the API request
var multipartFile = new http.MultipartFile('image_file', stream, length, filename: basename(_image.path));
// add file to multipart
request.files.add(multipartFile);
// send request to upload image
await request.send().then((response) async {
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}).catchError((e) {
print(e);
});
}
name spaces:
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
UPLOAD IMAGE TO SERVER WITH FORM DATA
To upload image to server you need a dio library.
Features:
Authorization (adding token)
Adding extra field like: username, etc
Adding Image to upload
Code example:
import 'package:dio/dio.dart' as dio;
import 'dart:convert';
try {
///[1] CREATING INSTANCE
var dioRequest = dio.Dio();
dioRequest.options.baseUrl = '<YOUR-URL>';
//[2] ADDING TOKEN
dioRequest.options.headers = {
'Authorization': '<IF-YOU-NEED-ADD-TOKEN-HERE>',
'Content-Type': 'application/x-www-form-urlencoded'
};
//[3] ADDING EXTRA INFO
var formData =
new dio.FormData.fromMap({'<SOME-EXTRA-FIELD>': 'username-forexample'});
//[4] ADD IMAGE TO UPLOAD
var file = await dio.MultipartFile.fromFile(image.path,
filename: basename(image.path),
contentType: MediaType("image", basename(image.path)));
formData.files.add(MapEntry('photo', file));
//[5] SEND TO SERVER
var response = await dioRequest.post(
url,
data: formData,
);
final result = json.decode(response.toString())['result'];
} catch (err) {
print('ERROR $err');
}
To add a header and use http multipart with https://pub.dev/packages/multi_image_picker Plugin,
This is the code.
var request = http.MultipartRequest(
'POST', Uri.parse(myurl)
);
//Header....
request.headers['Authorization'] ='bearer $authorizationToken';
request.fields['PropertyName'] = propertyName;
request.fields['Country'] = country.toString();
request.fields['Description'] = des;
request.fields['State'] = state.toString();
request.files.add(http.MultipartFile.fromBytes(
'ImagePaths',
learnImage,
filename: 'some-file-name.jpg',
contentType: MediaType("image", "jpg"),
)
);
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
print(res.body);
To use HTTP and https://pub.dev/packages/image_picker PLUGIN
This is the code
var request = http.MultipartRequest(
'POST', Uri.parse(myurl)
);
request.headers['Authorization'] ='bearer $authorizationToken';
request.fields['PropertyName'] = propertyName;
request.fields['Country'] = country.toString();
request.fields['Description'] = des;
request.fields['State'] = state.toString();
request.files.add(await http.MultipartFile.fromPath(
'ImagePaths',
file.path
)
);
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
print(res.body);
Working Code
String path = userSelectedImagePath;
Map<String, String> data = {
"name": firstName!,
"email": userEmail!
};
String token = await LocaldbHelper().getToken();
Map<String, String> headers = {
'X-Requested-With': 'XMLHttpRequest',
'authorization': 'Bearer $token',
};
var request = http.MultipartRequest(
'POST',
Uri.parse(ApiUrl.updateProfile),
);
request.fields.addAll(data);
request.headers.addAll(headers);
var multipartFile = await http.MultipartFile.fromPath(
'avatar', path); //returns a Future<MultipartFile>
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
final respStr = await response.stream.bytesToString();
var jsonData = jsonDecode(respStr);
if (response.statusCode == 200) {
// success
} else {
// error
}
Just leaving this here, if anyone is trying to upload a pdf or any other document using MultipartRequest method.
Just add the content type as -
contentType: new MediaType('application', 'pdf')
Good code with Dio and FilePicker for post file on your server. I use flutter for the web.
FilePicker
Dio
First you need writing Dio post method.
Future postImportClient(PlatformFile file) async {
try {
var urlBase = 'your url';
var mfile = MultipartFile.fromBytes(file.bytes!, filename: file.name);
var formData = FormData();
formData.files.add(MapEntry('file', mfile));
await _dio.post(urlBase, data: formData);
} on DioError catch (error) {
throw Exception(error);
}
}
Initial FilePicker and get file.
FilePickerResult? result = await FilePickerWeb.platform.pickFiles();
if (result != null) {
var file = result.files.single;
await client.postImportClient(file);
}
Good luck!
create FormData:
final formDataMap = <String, dynamic>{};
formDataMap["stringKey"] = "string";
List<MultipartFile> multipartImageList = [];
await Future.forEach(imagePaths as List<String>,(String path) async {
final multiPartFile = await MultipartFile.fromFile(
path,
contentType: MediaType("image", "jpeg"),
);
multipartImageList.add(multiPartFile);
});
formDataMap["image[]"] = multipartImageList;
final formData = FormData.fromMap(formDataMap);
With Retrofit & Dio:
#MultiPart()
#POST("{{url}}")
Future<dynamic> uploadFormData(
#Body() FormData formData,
);
With Hearder
upload image
Future uploadImageMedia(File fileImage, String token) async {
final mimeTypeData =
lookupMimeType(fileImage.path, headerBytes: [0xFF, 0xD8]).split('/');
final imageUploadRequest =
http.MultipartRequest('POST', Uri.parse(mainUrlSite + "wp-json/wp/v2/media"));
final file = await http.MultipartFile.fromPath('file', fileImage.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
imageUploadRequest.files.add(file);
imageUploadRequest.headers.addAll({
"Authorization": "Bearer " + token
});
try {
final streamedResponse = await imageUploadRequest.send();
streamedResponse.stream.transform(utf8.decoder).listen((value) {
print(value);
return Future.value(value);
});
} catch (e) {
print(e);
}
}
I use Dio library with put method:
var formData = FormData.fromMap({
'simpleParam': 'example',
'file': await MultipartFile.fromFile(filePath, filename: 'file.jpg')
});
var dio = Dio();
dio.options.headers[HttpHeaders.authorizationHeader] = myToken;
var response = new Response(); //Response from Dio
response = await dio.put(myUrl + "/myApi", data: formData);
The result is in response.data
try {
result[HttpKeys.status] = false;
var request = http.MultipartRequest('POST', url);
request.fields.addAll(body);
if (avatar.path.isNotEmpty) {
request.files.add(await http.MultipartFile.fromPath('uploadedImg', avatar.path));
}
request.headers.addAll(headers);
http.StreamedResponse streamResponse = await request.send();
final response = await http.Response.fromStream(streamResponse);
if (response.statusCode == 200) {
var resMap = jsonDecode(response.body);
debugPrint('<== π•Šπ•šπ•˜π•Ÿ 𝕦𝕑 𝕀𝕦𝕔𝕔𝕖𝕀𝕀𝕗𝕦𝕝𝕝π•ͺ ==>');
// debugPrint(response.body);
result[HttpKeys.status] = true;
result[HttpKeys.message] = resMap[HttpKeys.message];
result[HttpKeys.data] = resMap['data'];
return result;
} else {
var resMap = jsonDecode(response.body);
result[HttpKeys.message] = resMap[HttpKeys.message];
return result;
}
} catch (error) {
result[HttpKeys.message] = error.toString();
return result;
}
With dio I do like this:
Future<void> _uploadFileAsFormData(String path) async {
try {
final dio = Dio();
dio.options.headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
final file =
await MultipartFile.fromFile(path, filename: 'test_file');
final formData = FormData.fromMap({'file': file}); // 'file' - this is an api key, can be different
final response = await dio.put( // or dio.post
uploadFileUrlAsString,
data: formData,
);
} catch (err) {
print('uploading error: $err');
}
}

Image network did not change after uploading the image (flutter)

So, i make a feature to change profile pic. uploading successfully, then i try to get the new pict, but the pict is null because when i print the pict it shows the older pict instead of a new one.
seems like the image network didn't update automatically.
anybody can explain why this happen and how to fix it?
code for uploading
Future upload(File imageFile) async {
var stream = http.ByteStream(imageFile.openRead());
stream.cast();
var length = await imageFile.length();
String uuid = await UserPreference().getUuid();
var uri = Uri.parse("$baseUrl/customer/$uuid");
var request = http.MultipartRequest("POST", uri);
var multipartFile = http.MultipartFile('profile_picture', stream, length,
filename: basename(imageFile.path));
String getToken = await UserPreference().getToken();
request.headers.addAll({
'Content-Type': 'application/json',
HttpHeaders.authorizationHeader: "Bearer $getToken"
});
request.files.add(multipartFile);
var response = await request.send();
print(getToken);
if (response.statusCode == 200) {
print('uploaded');
} else {
print('failed');
}
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
the way i call the pic is
CircleAvatar(
radius: 50,
child: Image.network(
user.profile_picture!,
fit: BoxFit.cover,
),
),
Add setState once after response.
void uploadImage() async {
// Show loader
// open a byteStream
var stream = new
http.ByteStream(DelegatingStream.typed(file.openRead()));
// get file length
var length = await file.length();
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": token
}; // ignore this headers if there is no authentication
// string to uri
var uri = Uri.parse(Constants.BASE_URL);
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// if you need more parameters to parse, add those like this
// to the API request
request.fields["orderId"] = orderID.toString();
// multipart that takes file.. here this "file" is a key of the
// API request
var multipartFile = new http.MultipartFile('file', stream,
length,
filename: basename(file.path));
//add headers
request.headers.addAll(headers);
// add file to multipart
request.files.add(multipartFile);
// send request to upload image
await request.send().then((response) async {
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
setState(() {
if (response.statusCode == 200) {
print('uploaded');
} else {
print('failed');
}
});
// Hide loader
});
}).catchError((e) {
print(e);
// Hide loader
});
This will refresh the UI.

Upload image to Azure blob using Flutter (iOS/Android)

How can we upload images(.jpg, .png) to Azure blob storage. Not getting any insight to start with.
If you have used example would love to see and try if that is the way to do, any working example/url would help get started with
Here is i am trying to upload .jpg file and getting 400 error,
image.forEach((element) async {
ImageDetailsUpload result = ImageDetailsUpload.fromJson(element);
var postUri = Uri.parse('$url/${result.fileName}?$code'); //Azure blob url
var request = new http.MultipartRequest("PUT", postUri); //Put method
request.files.add(
new http.MultipartFile.fromBytes(
'file',
await File.fromUri(Uri.parse(result.path)).readAsBytes(),
),
);
request.send().then((response) {
print(response.statusCode);
}, onError: (err) {
print(err);
});
});
image is a LIST and holds the fileName and File path, this is what i get as bytes (see image below)
Solved the issue of upload but image is being corrupted now on server -
image.forEach((element) async {
ImageDetailsUpload result = ImageDetailsUpload.fromJson(element);
var postUri = Uri.parse('$url/${result.fileName}?$code');
var request = new http.MultipartRequest("PUT", postUri);
request.headers['X-MS-BLOB-TYPE'] = 'BlockBlob';
request.files.add(
new http.MultipartFile.fromBytes(
'file',
await File.fromUri(Uri.parse(result.path)).readAsBytes(),
),
);
request.send().then((response) {
print(response.statusCode);
}, onError: (err) {
print(err);
});
});
this seems to haunting me.
There is more to the question, what i noticed is the file uploaded using postman to blob storage are store as actual image of type image/jpeg depending on what type of image i am uploading. But when uploading using application i am using as mutipart which is making th e stored file into of type multipart/form-data. Uploaded both types of image jpg/png both gives type as mentioned above.
[![enter image description here][3]][3]
check here if you are using HTTP
How to upload images and file to a server in Flutter?
check this code if you are using Dio
FormData formData = FormData.from({
"name": "wendux",
"age": 25,
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt")
});
response = await dio.post("/info", data: formData);
and check Dio's documentation
https://pub.dev/packages/dio
Here is a working example from one of my codes
Future<UploadImageResultModel> uploadImage(File image, String memberToken,
{String type = "IMAGE"}) async {
var uri = Uri.parse('${Constants.baseUrl}member/UploadImage/$type');
var request = new http.MultipartRequest("POST", uri);
request.headers.addAll({
"Authentication": memberToken,
});
var stream = new http.ByteStream(DelegatingStream.typed(image.openRead()));
var length = await image.length();
var multipartFile = new http.MultipartFile('file', stream, length,
filename: image.path.split("/").last);
request.files.add(multipartFile);
var streamedResponse = await request.send();
var response = await http.Response.fromStream(streamedResponse);
if (response.statusCode != 200)
return UploadImageResultModel.fromJson(json.decode("{}"));
return UploadImageResultModel.fromJson(json.decode(response.body));
}
First, convert the image File to Stream as data will be a push to the blob container in form of a stream.
Future uploadImage(File file) async {
String fileName = file.path.split('/').last;
_logger.info("File Path: " + fileName);
String imageToken = "Get your own token";
String containerName = "Blob container name";
final fileBytes = file.readAsBytesSync();
var streamData = Stream.fromIterable(fileBytes.map((e) => [e]));
String uploadDestinationUrl = RollaConstants.HOST_IMAGE +
"/$containerName" +
"/$fileName" +
imageToken;
final Dio _dio = Dio();
Response response;
try {
response = await _dio.put(uploadDestinationUrl,
data: streamData,
options: Options(headers: {
Headers.contentLengthHeader: fileBytes.length,
"x-ms-blob-type": "BlockBlob",
"content-type": "image/jpeg"
}));
} catch (error, stacktrace) {
print("Exception occured: $error.response stackTrace: $stacktrace");
}
print("Blob response: " + response.statusCode.toString());
}

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

How to upload images and file to a server in Flutter?

I use a web service for image processing , it works well in Postman:
Now I want to make http request in flutter with Dart:
import 'package:http/http.dart' as http;
static ocr(File image) async {
var url = '${API_URL}ocr';
var bytes = image.readAsBytesSync();
var response = await http.post(
url,
headers:{ "Content-Type":"multipart/form-data" } ,
body: { "lang":"fas" , "image":bytes},
encoding: Encoding.getByName("utf-8")
);
return response.body;
}
but I don't know how to upload the image file, in above code I get exception: Bad state: Cannot set the body fields of a Request with content-type "multipart/form-data".
How should I write the body of request?
Your workaround should work; many servers will accept application/x-www-form-urlencoded as an alternative (although data is encoded moderately inefficiently).
However, it is possible to use dart:http to do this. Instead of using http.post, you'll want to use a http.MultipartFile object.
From the dart documentation:
var request = new http.MultipartRequest("POST", url);
request.fields['user'] = 'someone#somewhere.com';
request.files.add(http.MultipartFile.fromPath(
'package',
'build/package.tar.gz',
contentType: new MediaType('application', 'x-tar'),
));
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
I'd like to recommend dio package to you , dio is a powerful Http client for Dart/Flutter, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.
dio is very easy to use, in this case you can:
Sending FormData:
FormData formData = new FormData.from({
"name": "wendux",
"file1": new UploadFileInfo(new File("./upload.jpg"), "upload1.jpg")
});
response = await dio.post("/info", data: formData)
More details please refer to dio。
This can be achieved using the MultipartRequest class (https://pub.dev/documentation/http/latest/http/MultipartRequest-class.html)
Change the media type and uri as needed.
uploadFile() async {
var postUri = Uri.parse("<APIUrl>");
var request = new http.MultipartRequest("POST", postUri);
request.fields['user'] = 'blah';
request.files.add(new http.MultipartFile.fromBytes('file', await File.fromUri("<path/to/file>").readAsBytes(), contentType: new MediaType('image', 'jpeg')))
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
}
I found a working example without using any external plugin , this only uses
import 'package:http/http.dart' as http;
import 'dart:io';
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:convert';
Code
var stream =
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
// get file length
var length = await imageFile.length(); //imageFile is your image file
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": "Bearer " + token
}; // ignore this headers if there is no authentication
// string to uri
var uri = Uri.parse(Constants.BASE_URL + "api endpoint here");
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// multipart that takes file
var multipartFileSign = new http.MultipartFile('profile_pic', stream, length,
filename: basename(imageFile.path));
// add file to multipart
request.files.add(multipartFileSign);
//add headers
request.headers.addAll(headers);
//adding params
request.fields['loginId'] = '12';
request.fields['firstName'] = 'abc';
// request.fields['lastName'] = 'efg';
// send
var response = await request.send();
print(response.statusCode);
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
How to upload image file using restAPI in flutter/dart.
This work for me.
var postUri = Uri.parse("apiUrl");
http.MultipartRequest request = new http.MultipartRequest("POST", postUri);
http.MultipartFile multipartFile = await http.MultipartFile.fromPath(
'file', filePath);
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
print(response.statusCode);
Updated 2021 way:
using flutter http and mime
import 'package:mime/mime.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'dart:io';
Future<dynamic> multipartImageUpload(String baseUrl, String api, File image) async {
var uri = Uri.parse(baseUrl + api);
final mimeTypeData =
lookupMimeType(image.path, headerBytes: [0xFF, 0xD8]).split('/');
// Intilize the multipart request
final imageUploadRequest = http.MultipartRequest('PUT', uri);
// Attach the file in the request
final file = await http.MultipartFile.fromPath('image', image.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
imageUploadRequest.files.add(file);
// add headers if needed
//imageUploadRequest.headers.addAll(<some-headers>);
try {
final streamedResponse = await imageUploadRequest.send();
final response = await http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
print(e);
return null;
}
}
Use MultipartRequest class.
How to upload image file using restAPI in flutter/dart
void uploadImage1(File _image) async {
// open a byteStream
var stream = new http.ByteStream(DelegatingStream.typed(_image.openRead()));
// get file length
var length = await _image.length();
// string to uri
var uri = Uri.parse("enter here upload URL");
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// if you need more parameters to parse, add those like this. i added "user_id". here this "user_id" is a key of the API request
request.fields["user_id"] = "text";
// multipart that takes file.. here this "image_file" is a key of the API request
var multipartFile = new http.MultipartFile('image_file', stream, length, filename: basename(_image.path));
// add file to multipart
request.files.add(multipartFile);
// send request to upload image
await request.send().then((response) async {
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}).catchError((e) {
print(e);
});
}
name spaces:
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
UPLOAD IMAGE TO SERVER WITH FORM DATA
To upload image to server you need a dio library.
Features:
Authorization (adding token)
Adding extra field like: username, etc
Adding Image to upload
Code example:
import 'package:dio/dio.dart' as dio;
import 'dart:convert';
try {
///[1] CREATING INSTANCE
var dioRequest = dio.Dio();
dioRequest.options.baseUrl = '<YOUR-URL>';
//[2] ADDING TOKEN
dioRequest.options.headers = {
'Authorization': '<IF-YOU-NEED-ADD-TOKEN-HERE>',
'Content-Type': 'application/x-www-form-urlencoded'
};
//[3] ADDING EXTRA INFO
var formData =
new dio.FormData.fromMap({'<SOME-EXTRA-FIELD>': 'username-forexample'});
//[4] ADD IMAGE TO UPLOAD
var file = await dio.MultipartFile.fromFile(image.path,
filename: basename(image.path),
contentType: MediaType("image", basename(image.path)));
formData.files.add(MapEntry('photo', file));
//[5] SEND TO SERVER
var response = await dioRequest.post(
url,
data: formData,
);
final result = json.decode(response.toString())['result'];
} catch (err) {
print('ERROR $err');
}
To add a header and use http multipart with https://pub.dev/packages/multi_image_picker Plugin,
This is the code.
var request = http.MultipartRequest(
'POST', Uri.parse(myurl)
);
//Header....
request.headers['Authorization'] ='bearer $authorizationToken';
request.fields['PropertyName'] = propertyName;
request.fields['Country'] = country.toString();
request.fields['Description'] = des;
request.fields['State'] = state.toString();
request.files.add(http.MultipartFile.fromBytes(
'ImagePaths',
learnImage,
filename: 'some-file-name.jpg',
contentType: MediaType("image", "jpg"),
)
);
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
print(res.body);
To use HTTP and https://pub.dev/packages/image_picker PLUGIN
This is the code
var request = http.MultipartRequest(
'POST', Uri.parse(myurl)
);
request.headers['Authorization'] ='bearer $authorizationToken';
request.fields['PropertyName'] = propertyName;
request.fields['Country'] = country.toString();
request.fields['Description'] = des;
request.fields['State'] = state.toString();
request.files.add(await http.MultipartFile.fromPath(
'ImagePaths',
file.path
)
);
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
print(res.body);
Working Code
String path = userSelectedImagePath;
Map<String, String> data = {
"name": firstName!,
"email": userEmail!
};
String token = await LocaldbHelper().getToken();
Map<String, String> headers = {
'X-Requested-With': 'XMLHttpRequest',
'authorization': 'Bearer $token',
};
var request = http.MultipartRequest(
'POST',
Uri.parse(ApiUrl.updateProfile),
);
request.fields.addAll(data);
request.headers.addAll(headers);
var multipartFile = await http.MultipartFile.fromPath(
'avatar', path); //returns a Future<MultipartFile>
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
final respStr = await response.stream.bytesToString();
var jsonData = jsonDecode(respStr);
if (response.statusCode == 200) {
// success
} else {
// error
}
Just leaving this here, if anyone is trying to upload a pdf or any other document using MultipartRequest method.
Just add the content type as -
contentType: new MediaType('application', 'pdf')
Good code with Dio and FilePicker for post file on your server. I use flutter for the web.
FilePicker
Dio
First you need writing Dio post method.
Future postImportClient(PlatformFile file) async {
try {
var urlBase = 'your url';
var mfile = MultipartFile.fromBytes(file.bytes!, filename: file.name);
var formData = FormData();
formData.files.add(MapEntry('file', mfile));
await _dio.post(urlBase, data: formData);
} on DioError catch (error) {
throw Exception(error);
}
}
Initial FilePicker and get file.
FilePickerResult? result = await FilePickerWeb.platform.pickFiles();
if (result != null) {
var file = result.files.single;
await client.postImportClient(file);
}
Good luck!
create FormData:
final formDataMap = <String, dynamic>{};
formDataMap["stringKey"] = "string";
List<MultipartFile> multipartImageList = [];
await Future.forEach(imagePaths as List<String>,(String path) async {
final multiPartFile = await MultipartFile.fromFile(
path,
contentType: MediaType("image", "jpeg"),
);
multipartImageList.add(multiPartFile);
});
formDataMap["image[]"] = multipartImageList;
final formData = FormData.fromMap(formDataMap);
With Retrofit & Dio:
#MultiPart()
#POST("{{url}}")
Future<dynamic> uploadFormData(
#Body() FormData formData,
);
With Hearder
upload image
Future uploadImageMedia(File fileImage, String token) async {
final mimeTypeData =
lookupMimeType(fileImage.path, headerBytes: [0xFF, 0xD8]).split('/');
final imageUploadRequest =
http.MultipartRequest('POST', Uri.parse(mainUrlSite + "wp-json/wp/v2/media"));
final file = await http.MultipartFile.fromPath('file', fileImage.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
imageUploadRequest.files.add(file);
imageUploadRequest.headers.addAll({
"Authorization": "Bearer " + token
});
try {
final streamedResponse = await imageUploadRequest.send();
streamedResponse.stream.transform(utf8.decoder).listen((value) {
print(value);
return Future.value(value);
});
} catch (e) {
print(e);
}
}
I use Dio library with put method:
var formData = FormData.fromMap({
'simpleParam': 'example',
'file': await MultipartFile.fromFile(filePath, filename: 'file.jpg')
});
var dio = Dio();
dio.options.headers[HttpHeaders.authorizationHeader] = myToken;
var response = new Response(); //Response from Dio
response = await dio.put(myUrl + "/myApi", data: formData);
The result is in response.data
try {
result[HttpKeys.status] = false;
var request = http.MultipartRequest('POST', url);
request.fields.addAll(body);
if (avatar.path.isNotEmpty) {
request.files.add(await http.MultipartFile.fromPath('uploadedImg', avatar.path));
}
request.headers.addAll(headers);
http.StreamedResponse streamResponse = await request.send();
final response = await http.Response.fromStream(streamResponse);
if (response.statusCode == 200) {
var resMap = jsonDecode(response.body);
debugPrint('<== π•Šπ•šπ•˜π•Ÿ 𝕦𝕑 𝕀𝕦𝕔𝕔𝕖𝕀𝕀𝕗𝕦𝕝𝕝π•ͺ ==>');
// debugPrint(response.body);
result[HttpKeys.status] = true;
result[HttpKeys.message] = resMap[HttpKeys.message];
result[HttpKeys.data] = resMap['data'];
return result;
} else {
var resMap = jsonDecode(response.body);
result[HttpKeys.message] = resMap[HttpKeys.message];
return result;
}
} catch (error) {
result[HttpKeys.message] = error.toString();
return result;
}
Here is the code where I am passing Image, route which may be like '/register', and data which is Map<String, String> like data={'directory':'profile'}.
For Uploading Image to Laravel API, Authorization in header is compulsory otherwise it would return "You don't have permission to access this resource". I am passing token as EMPTY string like String token='' as I am uploading
Image at user registration time
This Authorization for read and write is defined in domainurl/public/.htaccess file, you can change it
Try to understand the below code and all the issue would be resolve.
Future uploadImage({
required XFile file,
required String route,
required Map<String, String> data,
}) async {
String url = API_Url + route;
final uri = Uri.parse(url);
try {
http.MultipartRequest request = http.MultipartRequest("POST", uri);
http.MultipartFile multipartFile =
await http.MultipartFile.fromPath('image', file.path);
request.files.add(multipartFile);
request.headers.addAll(_header());
request.fields.addAll(data);
var streamedResponse = await request.send();
var response = await http.Response.fromStream(streamedResponse);
print(jsonDecode(response.body));
return jsonDecode(response.body);
} catch (e) {
return null;
}
}
_header() {
return {"Content-Type": "multipart/form-data",
'Authorization': 'Bearer ${token}',
};
}
With dio I do like this:
Future<void> _uploadFileAsFormData(String path) async {
try {
final dio = Dio();
dio.options.headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
final file =
await MultipartFile.fromFile(path, filename: 'test_file');
final formData = FormData.fromMap({'file': file}); // 'file' - this is an api key, can be different
final response = await dio.put( // or dio.post
uploadFileUrlAsString,
data: formData,
);
} catch (err) {
print('uploading error: $err');
}
}