Upload image to server with Flutter Web - flutter

There is a web service, where you can send a form, it includes 2 images, this works well with Postman.
enter image description here
This code has been used, even with the Dio library, but it is the same error.
String token = '';
Future<String> uploadImage(File file) async {
String fileName ='HOLA.png';
Dio dio = new Dio();
FormData formData = FormData.fromMap({
'nombre_categoria': 'wendux',
'estado_categoria': 'activado',
'tipo_fastask': 'Fastask',
"img_icono":
await MultipartFile.fromFile(_image.name.toString(),
filename: fileName),
});
final response = await dio.post(
"locahost:7700/api/admin/servicios/agregar_categoria",
data: formData,
options: Options(headers: <String, String>{
'Authorization': 'Bearer ' + token,
}),
);
return response.data['id'];
}
Future obtenerimgen() async {
html.File imageFile =
await ImagePickerWeb.getImage(outputType: ImageType.file);
setState(() {
if(imageFile != null) {
print(imageFile.name.toString());
_image = imageFile;
} else {
print('No image selected.');
}
});
}

Related

Flutter: I am uploading a file to database using post api. But it gives me a bug

I am using file picker to pick the file. The file can be png jpg or pdf.
FilePickerResult? result =
await FilePicker.platform.pickFiles(
type: FileType.custom,
allowMultiple: true,
allowedExtensions: ['jpg', 'png', 'pdf'],
allowCompression: true,
);
setState(() {
if (result!.files.length != 0) {
_con!.thumbnail = result.files;
}
});
And the following is the code for uploading it to the database using post api using Dio library
Future uploadFile(BuildContext context) async {
setState(() {
isFormLoading = true;
});
var R;
Dio D = Dio();
D.options.headers = {
'Content-type': 'multipart/form-data',
// 'Content-type': 'application/json',
'Accept': 'application/json',
};
FormData formData = FormData.fromMap({
"image": DD.MultipartFile.fromFile(thumbnail.elementAt(0).path!),
});
R = await D.post(BASE_URL + "api/v2/upload/21", data: formData);
dynamic Response = R.data;
print('Response is >>>>>>');
print(R);
// BotToast.showText(text: Response["success"].toString());
setState(() {
isFormLoading = false;
});
}
modify the extension of the upload file file (jpg, png, pdf)
var formData = FormData.fromMap({
"file":
await MultipartFile.fromFile(path, filename: 'upload.jpg'),
});
Response response = await dio.post(
Constant().urlBase + Constant().confirm_package_reception,
data: formData);`enter code here`

I would like to upload a image and profile data in Multipart/Formdata format in flutter when hit a api i got response failed

Here is my post api code i try to upload file (image from image picker)and profilePojo(data like username ,fname, lastname etc.) when i run code i got result failed .
'''
void addData(final profilePojo) async {
SharedPreferences preferences = await SharedPreferences.getInstance();
String token = preferences.getString('token');
FormData formData = FormData.fromMap({
"file": await MultipartFile.fromFile("./text.txt",filename: "upload.txt"),
"profilePojo":profilePojo,//profilePojo means i pass heaar string of data on button click
});
String url =pass here url
http
.post(
url,
headers: {
HttpHeaders.authorizationHeader: 'Bearer $token',
// "Content-Type":"multipart/form-data",
"accept": "application/json",
},
body: formData.toString()
)
.then((response) {
if (response.statusCode == 200) {
var myData = json.decode(response.body);
if(myData['result']=="success"){
setState(() {
print(myData);//print response success
_showDialog();
getData();
});}
else{
print(response.statusCode);
print(myData);
}
} else {
print(response.statusCode);
print("object");
}
});
}
'''
I'm currently using dio for this kind of requests, here is my example:
final futureUploadList = imageList.map((img) async {
print(img.path);
return MultipartFile.fromFile(img.path);
});
final uploadList = await Future.wait(futureUploadList);
FormData data = FormData.fromMap({
"images": uploadList
});
dio.post('/images',
data: data, options: Options(headers: {'Authorization': 'Bearer abcd'}));

flutter dio upload files [pdf/ docs]

I am trying to upload files using dio package in my flutter application. I am sending my files through formdata. Here is my implementation:
Future<FormData> formData1() async {
return FormData.fromMap({
"title": "from app2",
"description": "app upload test",
"files": [
for (var i = 0; i < pathNames.length; i++)
await MultipartFile.fromFile(pathNames[i],
filename: fileNames[i])
]
});
}
Here is how I am sending my files.
_sendToServer() async {
Dio dio = Dio(
BaseOptions(
contentType: 'multipart/form-data',
headers: {
"Authorization": "$token",
},
),
);
dio.interceptors.add(
LogInterceptor(requestBody: true, request: true, responseBody: true));
FormData formData = await formData1();
try {
var response = await dio.post("http://url/api/upload",
data: formData, onSendProgress: (int send, int total) {
print((send / total) * 100);
});
print(response);
} on DioError catch (e) {
if (e.response != null) {
print(e.response.data);
print(e.response.headers);
print(e.response.request);
} else {
print(e.request.headers);
print(e.message);
}
}
}
The other fields in formdata are sent to the server but not the multipartfile. When I try and do the same from postman form-data, it uploads correctly. Am I doing something wrong here?
If you want to upload the file you can convert multipart array before calling API function because even if you put await in form data dio response will not wait for formdata object or you can use MultipartFile.fromFileSync() to get rid of await.
Let me show you in a simple way using my example. try to understand.
Multipart conversion
List multipartArray = [];
for (var i = 0; i < pathNames.length; i++){
multipartArray.add(MultipartFile.fromFileSync(pathNames[i], filename:
basename(pathNames[i])));
}
Api side
static Future<Response> createPostApi(multipartArray) async {
var uri = Uri.parse('http://your_base_url/post');
return await Dio()
.post('$uri',
data: FormData.fromMap({
"title": "from app2",
"description": "app upload test",
"files": multipartArray
}))
.catchError((e) {
print(e.response.data);
print(e.response.headers);
print(e.response.request);
});
}
Here is my code where I used file_picker flutter library and MediaType('application', 'pdf') to ensure that the content passed to the API was indeed a .pdf file.
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
static Future<dynamic> uploadfile(int userid, File file, String token) async {
var fileName = file.path.split('/').last;
print(fileName);
var formData = FormData.fromMap({
'title': 'Upload Dokumen',
'uploaded_file': await MultipartFile.fromFile(file.path,
filename: fileName, contentType: MediaType('application', 'pdf')),
"type": "application/pdf"
});
var response = await Dio().post('${urlapi}request/',
options: Options(
contentType: 'multipart/form-data',
headers: {HttpHeaders.authorizationHeader: 'Token $token'}),
data: formData);
print(response);
return response;
}
The file picker:
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path ??'file.pdf');
BlocProvider.of<UploadCubit>(context)
.uploadFile(statelogin.user.id, file,
statelogin.user.token);
}
Change formdata with following rest is fine
import 'package:path/path.dart' as pathManager;
import 'package:mime/mime.dart' as mimeManager;
FormData formdata = FormData();
formdata.add(
"files",
[UploadFileInfo(img, pathManager.basename(img.path),
contentType:
ContentType.parse(mimeManager.lookupMimeType(img.path)))]);
// here attachmentFile is File instance, which is set by File Picker
Map<String, dynamic> _documentFormData = {};
if (attachmentFile != null) {
_documentFormData['document_file'] = MultipartFile.fromFileSync(attachmentFile.path);
}
FormData formData = FormData.fromMap(_documentFormData);
try {
var response = await dio.post("http://url/api/upload",
data: formData, onSendProgress: (int send, int total) {
print((send / total) * 100);
});
print(response);
} on DioError catch (e) {
if (e.response != null) {
print(e.response.data);
print(e.response.headers);
print(e.response.request);
} else {
print(e.request.headers);
print(e.message);
}
}
Here you can use MultipartRequest class without using any of library to upload any kind of files using restAPI.
void uploadFile(File file) async {
// 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 "idDocumentOne_1" is a key of the API request
MultipartFile multipartFile = await http.MultipartFile.fromPath(
'idDocumentOne_1',
file.path
);
// add file to multipart
request.files.add(multipartFile);
// send request to upload file
await request.send().then((response) async {
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}).catchError((e) {
print(e);
});
}
I used file picker to pick file. Here is the codes for pick file.
Future getPdfAndUpload(int position) async {
File file = await FilePicker.getFile(
type: FileType.custom,
allowedExtensions: ['pdf','docx'],
);
if(file != null) {
setState(() {
file1 = file; //file1 is a global variable which i created
});
}
}
here file_picker flutter library.

How can i post image with dio in flutter

i want to send image to server by jpg format by dio package ,
how can i do this ?
choose image method :
void _chooseImageCamera() async {
file = await ImagePicker.pickImage(source: ImageSource.camera,imageQuality: 50);
setState(() {
file = file;
print(file);
});
upload image method :
void _upload() async {
if (file == null) return;
String fileName = file.path.split('/').last;
Map<String, dynamic> formData = {
"image": await MultipartFile.fromFile(file.path,filename: fileName),
};
await serverRequest().getRequest("/Information", formData).then((onValue) {
print(json.decode(onValue));
});
Anyone help me ?
thanks
Please try this
Future<dynamic> _upload() async {
if (file == null) return;
String fileName = file.path.split('/').last;
Map<String, dynamic> formData = {
"image": await MultipartFile.fromFile(file.path,filename: fileName),
};
return await Dio()
.post(url,data:formData).
then((dynamic result){
print(result.toString());
});
}
You can also use http for this purpose
Future<String> uploadImage(Asset asset,String orderId) async {
// String to uri
Uri uri = Uri.parse('Your URL');
// create multipart request
http.MultipartRequest request = http.MultipartRequest("POST", uri);
ByteData byteData = await asset.getByteData();
List<int> imageData = byteData.buffer.asUint8List();
http.MultipartFile multipartFile = http.MultipartFile.fromBytes(
'image',
imageData,
filename: '${DateTime.now().millisecondsSinceEpoch}.jpg',
contentType: MediaType("image", "jpg"),
);
// Add field to your request
request.fields['FieldName'] = fieldValue;
// add file to multipart
request.files.add(multipartFile);
// send
var response = await request.send();
// Decode response
final respStr = await response.stream.bytesToString();
return respStr;
}

How to upload images to server in Flutter?

I would like to upload a image, I am using http.Client() for making requests,
static uploadImage(String id, File file) {
var httpClient = createHttpClient();
Map<String, String> headers = new Map<String, String>();
headers.putIfAbsent("Authorization", () => "---");
headers.putIfAbsent("Content-Type", () => "application/json");
var body=new List();
body.add(id.)
httpClient.post(URL_UPLOADIMAGE,headers: headers,body: ,encoding: )
}
What should be the body and encoding part for the request ?
Use MultipartRequest class
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);
});
}
name spaces:
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
The easiest way is to use the http library,
import 'dart:io';
import 'package:http/http.dart' as http;
_asyncFileUpload(String text, File file) async{
//create multipart request for POST or PATCH method
var request = http.MultipartRequest("POST", Uri.parse("<url>"));
//add text fields
request.fields["text_field"] = text;
//create multipart using filepath, string or bytes
var pic = await http.MultipartFile.fromPath("file_field", file.path);
//add multipart to request
request.files.add(pic);
var response = await request.send();
//Get the response from the server
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
print(responseString);
}
Checkout the body in submitForm() method.
File _image;
Future cameraImage() async {
var image = await ImagePicker.pickImage(
source: ImageSource.camera,
maxHeight: 240.0,
maxWidth: 240.0,
);
setState(() {
_image = image;
});
}
submitForm() async {
final response = await http.post(
uri,
headers: {
AuthUtils.AUTH_HEADER: _authToken
},
body: {
'user_id': userId
'photo': _image != null ? 'data:image/png;base64,' +
base64Encode(_image.readAsBytesSync()) : '',
},
);
final responseJson = json.decode(response.body);
print(responseJson);
}
I have tried all the above but none worked for me to upload a file to a server.
After a deep search, I got a plugin the same as Dio.
The following code uploads a file to a server.
uploadFileFromDio(UserProfile userProfile, File photoFile) async {
var dio = new Dio();
dio.options.baseUrl = url;
dio.options.connectTimeout = 5000; //5s
dio.options.receiveTimeout = 5000;
dio.options.headers = <Header Json>;
FormData formData = new FormData();
formData.add("user_id", userProfile.userId);
formData.add("name", userProfile.name);
formData.add("email", userProfile.email);
if (photoFile != null &&
photoFile.path != null &&
photoFile.path.isNotEmpty) {
// Create a FormData
String fileName = basename(photoFile.path);
print("File Name : $fileName");
print("File Size : ${photoFile.lengthSync()}");
formData.add("user_picture", new UploadFileInfo(photoFile, fileName));
}
var response = await dio.post("user/manage_profile",
data: formData,
options: Options(
method: 'POST',
responseType: ResponseType.PLAIN // or ResponseType.JSON
));
print("Response status: ${response.statusCode}");
print("Response data: ${response.data}");
}
I found a working example without using any external plugin , this
only uses
import 'package:http/http.dart' as http;
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);
});
Please try below solution
Future<String> uploadImageHTTP(file, url) async {
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(await http.MultipartFile.fromPath('picture', file.path));
var res = await request.send();
return res.reasonPhrase;
}
Consider using Flutter's Firebase Storage plugin -- it has features that could be useful for uploading large image files on a mobile connection.
I wrote the plugin, contributions and feedback are welcome!
First of all choose your image from gallery or Camera
File _image;
Future _getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
});
}
Now call the below function on button click or inside the _getImage() function. With the file i'm uploading other fields also you see in the saveInAttendance()
Don't forget to import package :
import 'package:dio/dio.dart';
import 'package:path/path.dart';
Future saveInAttendance( BuildContext context,String entryType,String mode) async {
Dio dio = new Dio();
FormData formData = new FormData(); // just like JS
formData.add("inimageFile", new UploadFileInfo(_image, basename(_image.path)));
formData.add("compID",2);
formData.add("company_id",2);
formData.add("EntryType", entryType);
formData.add("emp_code", 5);
formData.add("Mode",mode);
formData.add("location",""+_startLocation.latitude.toString()+"-"+_startLocation.longitude.toString());
dio.post(url_save_attendance, data: formData, options: Options(
method: 'POST',
responseType: ResponseType.json // or ResponseType.JSON
))
.then((r) {
setState(() {
var data = json.decode(r.toString());
if(data["apiMessage"].contains('Saved')){
warningAlert("Attendance Saved", "Your attendance saved Successfully",context);
}
});
}).catchError(print);
}
For more Info you can visit Here
my working code below, based on #TejaDroid's sample,
it upload one image via the AWS Gateway API with a lambda function behind to store the image into S3.
uploadImageWithhttp(File imageFile, int serialno) async {
var postBody= {
'username': 'test#gmail.com',
"productid": "1000123", //TODO
"imageno": serialno.toString(),
'image': imageFile != null ? base64Encode(imageFile.readAsBytesSync()) : '',
};
final response = await http.post(
constAWSAPIGateway_UploadImage[CONST_API_STAGE],
headers: {
//AuthUtils.AUTH_HEADER: _authToken
'Content-Type' : 'application/json',
},
body: json.encode(postBody),
);
final responseJson = json.decode(response.body);
print(responseJson);
}
to get Body from request Instead of
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
I use:
String body=await response.stream.bytesToString()
updateProfile() async {
try {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
var dio = new Dio();
var formData = FormData.fromMap({
'name': name,
'con_person_name': concernedPersonName,
'email': email,
'phone': phoneNumber,
'password': password,
'token': token,
'user_type': '3',
'license_no': licenceNumber,
'gstno': gstNumber,
'address': address,
'hospital_id': '102'
'image': await MultipartFile.fromFile(_image?.path,
filename: _image.path.split('/').last ?? 'image.jpeg'),
});
var response = await dio.post('$SERVER_ADDRESS/api/doctorregister',
data: formData);
print(response.statusCode);
print(response.data);
}
} catch (error) {
print(error.toString());
}
}
Import dio, image_picker library
Future _onGalleryPressed() async {
Future<File> image = ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
this._imageFile = image;
});
File img = await image;
Navigator.of(context).pop();
if (img != null) {
//API CALL
try {
FormData formData = new FormData.from({"file": path});
var url = backendUrl + "/upload-image";
var token = await _getMobileToken();
Map<String, String> headers = {
'Authorization': 'Bearer $token',
"Content-Type": "multipart/form-data",
"X-Requested-With": "XMLHttpRequest"
};
await dio.post(url,
data: formData,
options: Options(
method: 'POST',
headers: headers,
responseType: ResponseType.json // or ResponseType.JSON
));
Navigator.pop(context);
} catch (e) {}
}
}
If you want to upload it as a binary file.
static uploadFile(File imageFile) async {
final response = await http.post(postURL, body: imageFile.readAsBytesSync());
return json.decode(response.body);
}
Thank you
I have checked about it at multiple places finally i found a solution -
var objToSend = {
"file": await MultipartFile.fromFile(
file.path,
filename: filename,
),
};
FormData formData = FormData.fromMap(objToSend);
print(formData.files.toString());
Dio dio = new Dio();
await dio
.post(_toSend,
data: formData,
options: Options(
method: 'POST',
headers: <String, String>{
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Authorization": 'Bearer ' + token
},
))
.whenComplete(() {
print('uploaded');
}).catchError((onError) {
print('failed');
});
I have found a easy way to upload images in flutter and then even receiving it on the server.
Flutter:
MaterialButton(
color: Colors.blue,
child: Text(
"Pick Image from Camera",
style: TextStyle(
color: Colors.white70, fontWeight: FontWeight.bold),
),
onPressed: () async {
final XFile? photo =
await _picker.pickImage(source: ImageSource.camera);
print(photo!.path);
await uploadImage(photo.path);
},
),
'uploadImage' function:
uploadImage(String filepath) async {
var url = 'http://192.168.75.57:4000/upload';
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(await http.MultipartFile.fromPath("img", filepath));
request.fields['_id'] = "abcdef";
request.headers.addAll({
"Content-type": "multipart/form-data",
});
var response = request.send();
return response;
}
On the server Side: (Nodejs)
For this, first install multer (npm install multer)
const multer = require('multer');
const path = require('path')
const storage = multer.diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
cb(null, (new Date()).getTime().toString() + ".jpg");
},
});
const fileFilter = (req, file, cb) => {
if (file.mimetype == "image/jpeg" || file.mimetype == "image/png") {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 6,
},
fileFilter: fileFilter,
});
Finally, honoring the request from flutter application:
(In router.js)
router.post('/upload', upload.single("img"), function (req, res) {
console.log("hit")
console.log(req.body._id)
res.send("ok")
})
This method worked for me and I found it comparatively easier than other methods.