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
Related
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");
}
}
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.");
}
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 '';
}
}
}
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.
This question already has an answer here:
Upload image with http.post and registration form in Flutter?
(1 answer)
Closed 3 years ago.
I am new to Flutter development. My problem is that I try to upload the image but I keep getting failed request.
This piece of code is where I connect it with a server API which will receive the image file from Flutter. String attachment which consist of the image path that is passed from createIncident function located at another page.
Future<IncidentCreateResponse> createIncident( String requesterName, String requesterEmail,
String requesterMobile, String attachment, String title,
String tags, String body, String teamId,
String address ) async {
IncidentCreateResponse incidentCreateResponse;
var url = GlobalConfig.API_BASE_HANDESK + GlobalConfig.API_INCIDENT_CREATE_TICKETS;
var token = Auth().loginSession.accessToken;
var postBody = new Map<String, dynamic>();
postBody["requester_name"] = requesterName;
postBody["requester_email"] = requesterEmail;
postBody["requester_mobile_no"] = requesterMobile;
postBody["attachment"] = attachment;
postBody["title"] = title;
postBody["tags"] = tags;
postBody["body"] = body;
postBody["teamId"] = teamId;
postBody["address"] = address;
// Await the http get response, then decode the json-formatted responce.
var response = await http.post(
url,
body: postBody,
headers: {
'X-APP-ID': GlobalConfig.APP_ID,
"Accept": "application/json; charset=UTF-8",
// "Content-Type": "application/x-www-form-urlencoded",
HttpHeaders.authorizationHeader: 'Bearer $token',
'token': GlobalConfig.API_INCIDENT_REPORT_TOKEN
}
);
if ((response.statusCode == 200) || (response.statusCode == 201)) {
print(response.body);
var data = json.decode(response.body);
incidentCreateResponse = IncidentCreateResponse.fromJson(data['data']);
} else {
print("createIncident failed with status: ${response.statusCode}.");
incidentCreateResponse = null;
}
return incidentCreateResponse;
}
This is the code snippet where I get the image path from the selected image from the gallery
Future getImageFromGallery(BuildContext context) async {
var picture = await ImagePicker.pickImage(source: ImageSource.gallery);
setState((){
_imageFile = picture;
attachment = basename(_imageFile.path);
});
Navigator.of(context).pop();
}
This is the code where I passed the attachment string to the HTTP Response
this.incidentService.createIncident(
Auth().loginSession.name,
Auth().loginSession.email,
Auth().loginSession.mobile_no,
this.attachment,
this._titleController.text,
this._tags,
this._contentController.text,
this._teamId,
this._addressController.text
).then((IncidentCreateResponse res) {
if (res != null) {
print('Ticket Id: ' + res.id);
// Navigator.pop(context);
this._successSubmittionDialog(context);
} else {
this._errorSubmittionDialog(context);
}
}
You can upload image using multipart or base64 Encode.
For uploading image using multipart Visit the Official documentation
For uploading image using base64 Encode you can checkout the Tutorial Here
I suggest using multipart image upload as it is even reliable when your image or files are larger in size.
Hope this could help you,
create a function to upload your image after picking or clicking an image like,
Future<ResponseModel> uploadPhoto(
String _token,
File _image,
String _path,
) async {
Dio dio = new Dio();
FormData _formdata = new FormData();
_formdata.add("photo", new UploadFileInfo(_image, _path));
final response = await dio.post(
baseUrl + '/image/upload',
data: _formdata,
options: Options(
method: 'POST',
headers: {
authTokenHeader: _token,
},
responseType: ResponseType.json,
),
);
if (response.statusCode == 200 || response.statusCode == 500) {
return ResponseModel.fromJson(json.decode(response.toString()));
} else {
throw Exception('Failed to upload!');
}
}
then you can use use uploadImage,
uploadImage(_token, _image,_image.uri.toFilePath()).then((ResponseModel response) {
//do something with the response
});
I have used Dio for the task, you can find more detail about dio here
Add this to your package's pubspec.yaml file:
dependencies:
dio: ^3.0.5
Then import it in your Dart code, you can use:
import 'package:dio/dio.dart';
To upload image using multipart API use this code ie
Add this library dio in your project in pubspec.yaml file
dio: ^3.0.5
and import this in your class
import 'package:dio/dio.dart';
Declare this variable in your class like State<CustomClass>
static var uri = "BASE_URL_HERE";
static BaseOptions options = BaseOptions(
baseUrl: uri,
responseType: ResponseType.plain,
connectTimeout: 30000,
receiveTimeout: 30000,
validateStatus: (code) {
if (code >= 200) {
return true;
}
});
static Dio dio = Dio(options);
then use this method to upload file
Future<dynamic> _uploadFile() async {
try {
Options options = Options(
//contentType: ContentType.parse('application/json'), // only for json type api
);
var directory = await getExternalStorageDirectory(); // directory path
final path = await directory.path; // path of the directory
Response response = await dio.post('/update_profile',
data: FormData.from({
"param_key": "value",
"param2_key": "value",
"param3_key": "value",
"profile_pic_param_key": UploadFileInfo(File("$path/pic.jpg"), "pic.jpg"),
}),
options: options);
setState(() {
isLoading = false;
});
if (response.statusCode == 200 || response.statusCode == 201) {
var responseJson = json.decode(response.data);
return responseJson;
} else if (response.statusCode == 401) {
print(' response code 401');
throw Exception("Incorrect Email/Password");
} else
throw Exception('Authentication Error');
} on DioError catch (exception) {
if (exception == null ||
exception.toString().contains('SocketException')) {
throw Exception("Network Error");
} else if (exception.type == DioErrorType.RECEIVE_TIMEOUT ||
exception.type == DioErrorType.CONNECT_TIMEOUT) {
throw Exception(
"Could'nt connect, please ensure you have a stable network.");
} else {
return null;
}
}
}