Unhandled Exception: FileSystemException: Cannot open file, path = 'PlatformFile in Flutter - flutter

I'm trying to post PaltformFiles to the server using Multipart Requests but keep getting the above error for some strange reason. I would like to know what I can do to resolve this error. The code I have written is given below.
File Picker Method:
onTap: () async {
final filePickerOne = await FilePicker.platform
.pickFiles(
type: FileType.custom,
allowedExtensions: [
'pdf',
'jpg',
'jpeg',
'png'
]);
if (filePickerOne == null) return;
final fileOne = filePickerOne.files.first;
openFile(fileOne);
print('Name: ${fileOne.name}');
setState(() {
fileOneName = fileOne.name;
panDoc = fileOne;
});
print('Bytes: ${fileOne.bytes}');
print('Size: ${fileOne.size}');
print('Extension: ${fileOne.extension}');
print('Path: ${fileOne.path}');
The API Request:
Future<void> postMethod(
String? organizationName,
String? telephoneNumberOne,
String? telephoneNumberTwo,
String? companyPanCard,
PlatformFile? panCard,
String? aadharUdyamUdoyog,
PlatformFile? aadharCard,
String? gstNumber) async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
// final File filePanCard = File(panCard!.path.toString());
// final File fileAadharCard = File(aadharCard!.path.toString());
final url = Uri.parse(baseUrl + 'api/vendor/profile/business/');
var request = http.MultipartRequest('POST', url);
request.headers
.addAll({'Authorization': 'Bearer ${localStorage.getString('token')}'});
request.fields['org_name'] = organizationName!;
request.fields['telephone_1'] = telephoneNumberOne!;
request.fields['telephone_2'] = telephoneNumberTwo!;
request.fields['company_pancard'] = companyPanCard!;
request.files.add(http.MultipartFile.fromBytes(
'company_pancard_doc', File(panCard!.toString()).readAsBytesSync())); //This is where the error gets thrown
request.fields['adhar_udyam_udoyog'] = aadharUdyamUdoyog!;
request.files.add(http.MultipartFile.fromBytes('adhar_udyam_udoyog_doc',
File(aadharCard!.toString()).readAsBytesSync())); //Resolving the aboe error will hopefully resolve this one as well.
request.fields['gst_number'] = gstNumber!;
var response = await request.send();
print('Response: $response');
if (response.statusCode == 200) {
print('Uploaded');
} else {
print('Failed');
}
}
Any Ideas? Do let me know If you more info.

Related

Converting object to an encodable object failed: Instance of '_File' Flutter

I'm trying to post an image to API.
This is my Post Function :
Future<http.Response> ajoutProduit(
String refProduit,
String nomProduit,
double prixAchatProduit,
double prixVenteProduit,
String descriptionProduit,
File imageProduit) async {
List produits = [];
final response = await http.post(
Uri.parse('http://127.0.0.1:8000/api/produit/'),
headers: <String, String>{'Content-Type': 'multipart/form-data'},
body: jsonEncode(<String, dynamic>{
'refProd': refProduit,
'nomProd': nomProduit,
'prixAchat': prixAchatProduit,
'prixVente': prixVenteProduit,
'descriptionProd': descriptionProduit,
'imageProd': imageProduit,
}),
);
if (response.statusCode == 200) {
return produits = jsonDecode(response.body);
} else {
throw Exception('Erreur base de données!');
}
}
and this is my ImagePicker function :
File uploadimage;
Future<void> chooseImage() async {
final ImagePicker picker = ImagePicker();
var choosedimage = await picker.pickImage(source: ImageSource.gallery);
final File convertimage = await File(choosedimage.path);
setState(() {
uploadimage = convertimage;
});
}
Finally, this is the confirm button :
ElevatedButton(
onPressed: (() {
if (_formKey.currentState.validate()) {
setState(() {
future = ajoutProduit(
refProduit.text,
nomProduit.text,
double.parse(prixAchatProduit.text),
double.parse(prixVenteProduit.text),
descriptionProduit.text,
uploadimage);
});
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Produit Ajouté')),
);
Navigator.of(context, rootNavigator: true).pop();
}
}), ...
When i press the button i get this error in the debug console :
Error: Converting object to an encodable object failed: Instance of '_File'
I would suggest uploading the file as form you can do something like the following
List<http.MultipartFile> files = [await http.MultipartFile.fromPath('file', file.path)];
http.MultipartRequest request = new http.MultipartRequest("POST", uri);
for (http.MultipartFile file in files) {
request.files.add(file);
}
http.StreamedResponse responseStream = await request.send();
http.Response response = await
http.Response.fromStream(responseStream).timeout(Duration(seconds: timeoutSeconds));

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

Image Upload in Flutter Using Http post method

I'm new in this Framework and I want to Upload the Image along with the User name id and wmail and phone,
but Unable to to that I'm getting error
this is the Image get image function
File _image;
final picker = ImagePicker();
Future getImage() async {
pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
} else {
print('No image selected.');
}
});
}
Here i have written the Code for Upkoadung How to do Please help me with that
Future updateUserApiCall(
String name, String email, String mobile, File profile) async {
String token;
var userId;
SharedPreferences storage = await SharedPreferences.getInstance();
token = storage.getString("apiToken");
userId = storage.getInt("id");
String url = "https://www.example.com/api/updateprofile";
final response = await http.post(
url + "?page=" + "",
body: json.encode({
'user_id': userId,
'email': email,
'name': name,
'phone': mobile,
'image': profile,
}),
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Bearer " + token,
},
);
if (response.statusCode == 200) {
print(response.body);
return UpdateProfileResponseModel.fromJson(
json.decode(response.body),
);
} else if (response.statusCode == 400) {
print(response.body);
return ErrorResponseModel.fromJson(
json.decode(response.body),
);
} else if (response.statusCode == 422) {
print(response.body);
return ValidationErrorResponseModel.fromJson(
json.decode(response.body),
);
} else {
print(response);
throw Exception('Failed to load data!');
}
}
}
As far as I know you can not pass image data using just http.post method. You have to use Multipart Request. I have also faced similar problem and asked a similar question in StackOverFlow. Please check the link below:
uploading image using file_picker flutter to a nodejs server
My use case was updating image of an user, I have used the following code to send image to a node server.
Future<bool> updateImage(File imageFile, AuthModel authModel) async{
final String _accessToken = 'abc';
final String url =
'https://justyourserverURL.com/update';
print("auth : " + _accessToken);
var request = http.MultipartRequest('POST', Uri.parse(url));
request.headers['Authorization'] = _accessToken;
// request.fields['id'] = '104';
// request.fields['firstName'] = authModel.data.firstName;
// request.fields['lastName'] = authModel.data.lastName;
// request.fields['surname'] = authModel.data.surname;
request.files.add(await http.MultipartFile.fromPath('file', imageFile.path));
var res = await request.send();
final respStr = await res.stream.bytesToString();
print('responseBody: ' + respStr);
if(res.statusCode==200){
setCurrentUser(respStr);
currentUser = authModelFromJson(respStr);
return true;
} else {
print(respStr);
print('Failed');
return false;
}
}
To pass username or id just pass data using request.fields['user_id'] = userId.

How to Show Snackbar with the Result of Future Http Post?

I'm trying to get a "File was uploaded." string back from a successful Future HTTP post request so that I can create a SnackBar but all I get back from the return is null. Here's the button which calls the Future;
IconButton(
icon: Icon(TriangleAll.upload_3, ),
onPressed: () async {
replyresult = await uploadReply(
filepath: _current.path);
)
if (replyresult != null){
print(replyresult);
}
}
)
And here's the code for the future;
Future<String> uploadReply(
}) async {
final serverurl = "http://example.com/example.php";
final filepath = "examplefilepath";
String serverResponse;
var request = http.MultipartRequest('POST', Uri.parse(serverurl));
var multiPartFile = await http.MultipartFile.fromPath("audio", filepath,
contentType: MediaType("audio", "mp4"));
request.files.add(multiPartFile);
request.send().then((result) async {
http.Response.fromStream(result).then((response) {
if (response.statusCode == 200) {
serverResponse = response.body;
print(serverResponse);
return serverResponse ;
}
});
});
}
I'm trying to use the replyresult variable to create the snackbar upon a successful 200 server response. I know the post is successful as I can see the correct printed serverResponsein the console.
I've tried to simply do;
return response.body ;
But I'm still getting null at the replyresult variable.
because the method returns before the response arrives in Future, do this
var response = await http.Response.fromStream(result);
if (response.statusCode == 200) {
serverResponse = response.body;
print(serverResponse);
return serverResponse ;
} else return '';
or a single await ahead of the Future.
This is what worked.
var multiPartFile = await http.MultipartFile.fromPath("audio", filepath,
contentType: MediaType("audio", "mp4"));
request.files.add(multiPartFile);
final response = await http.Response.fromStream(await request.send());
String serverResponse;
if (response.statusCode == 200) {
String serverResponse = response.body;
print(serverResponse);
return serverResponse;
}

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