I want to upload an image that I have already retrieved from the database(product table) to the cart table.
The issue is, I can't use the .path with the MultipartFile("file", image.path);
I am getting an error if I try using .path with my image variable. I've also tried several methods but none is working... I'll attach my codes below
The image is already stored in a map(revievedMap) which I receivr from the previous screen so I'm not using an imagePicker, the product image I'm trying to access is already stored in the database.
request.fields['image'] = "http://10.0.2.2:/shopice/assets/${args.product.image}";
request.fields['image'] = "http://localhost:/shopice/assets/${args.product.image}";
I tried the code above, obviously didn't work.
var pic = await http.MultipartFile.fromPath("image", args.product.image!);
//request.files.add(pic);
I also tried this, but I need to set the path on the second argument, but args.product.image.path(), is returning this error
[the getter 'path' isn't defined for the type 'String'. (Documentation) Try importing the library that defines 'path', correcting the name to the name of an existing getter, or defining a getter or field named 'path'.]
here is the code:
//args.receivedMap: is my buyer detials
//args.product: is the product i'm trying to add to cart, which //contains the image
args.seller: is the seller details
child: FlatButton(
onPressed: ()async {
if(!args.receivedMap.isEmpty){
final uri = Uri.parse("http://10.0.2.2:/shopice/api/buyer/addToCart");
var request = http.MultipartRequest('POST', uri);
request.fields['buyer_id'] =args.receivedMap['id'];
request.fields['seller_id'] = args.seller.id.toString();
request.fields['seller_name'] = args.seller.name!;
request.fields['buyer_name'] = args.receivedMap['name'];
request.fields['price'] = args.product.pricePerKg!;
request.fields['product_name'] = args.product.name!;
//request.fields['image'] = "http://10.0.2.2:/shopice/assets/${args.product.image}";
//var pic = await http.MultipartFile.fromPath("image", "http://localhost:/shopice/assets/${args.product.image}");
//File file = "http://10.0.2.2:/shopice/assets/${args.product.image}" as File;
//var pic = await http.MultipartFile.fromString("image", args.product.image!);
//request.files.add(pic);
var bytes = (await rootBundle.load('http://localhost/shopice/assets/${args.product.image}')).buffer.asUint8List();
var mpFile = http.MultipartFile.fromBytes('img', bytes);
request.files.add(mpFile);
var response = await request.send();
print(args.product.image);
if (response.statusCode == 200) {
showModalBottomSheet(context: context, builder: (context){
return Wrap(children: [ListTile(leading: Icon(Icons.done_outline), title: Text('Product Added TO Cart'),)],);
});
}
else if (response.statusCode == 500) {
showModalBottomSheet(context: context, builder: (context){
return Wrap(children: [ListTile(leading: Icon(Icons.done_outline), title: Text('Server Error '),)],);
});
}
else {
showModalBottomSheet(context: context, builder: (context){
return Wrap(children: [ListTile(leading: Icon(Icons.done_outline), title: Text('ERROR WHILE PERFORMING OPPERATION\n CONTACT SUPPORT'),)],);
});
}
}
else if(args.receivedMap.isEmpty){
var snackbar = SnackBar(
content: Text('Login To Add Product To Cart!',
style: TextStyle(fontSize: 16.0)),
backgroundColor:
const Color(0xff4A777A),
padding: EdgeInsets.only(left: 50.0),
);
ScaffoldMessenger.of(context)
.showSnackBar(snackbar);
}
},
child: Text(
'Add to Cart',
style: GoogleFonts.poppins(
color: Color(0xff4A777A)),
)),
i simply add the image from the backend and forget about doing it with flutter, i moved the image with php and did some trial and error which later worked
So I have this code that picks the image
Container(
child: ElevatedButton(
onPressed: () async {
result = await FilePicker.platform
.pickFiles(allowMultiple: true);
if (result == null) {
print("No file selected");
} else {
setState(() {
result?.files.forEach((element) {
attachmentController.text =
element.name;
statusController.text = "pending";
});
});
result?.files.forEach((element) {
print(element.name);
});
}
},
and I wanted to send this image to the backend of laravel but first, I have an attachment controller that saves the element.name but turns out it's just a name. May I please know how to save the image in the controller and if any links to show how to save that in the laravel backend please?
Thank you
If you are only picking images i will suggest you to use the image_picker package.
In your widget file :
File? image;
...
image= await ImagePicker.pickImage(source: ImageSource.gallery);
setState({});
You can use Image.file, widget factory method to show the image.
In your Api file :
import 'package:http/http.dart' as http;
import 'dart:convert';
...
var response = await http.post('example.com/api',
body: {
'image': base64Encode(await imageFile.readAsBytes()),
},
);
Depending on your Laravel you handle the request, decode it from base64 and save it to a folder.
I'm making a travel app about Crete where people can look up the most important things to see. They can also add documents to their own trips, which is a collection on firestore "Selected".
I want people to be able to generate a pdf from their selected items, to save on their Android/Iphone.
I have a seperate class for generating the pdf..
But how do I pass snapshot.data() to the other class?
onTap: () async {
getSelectedItems();
final pdfFile = await PdfApi.generateCenteredText(data);
PdfApi.openFile(pdfFile);
},
getSelectedItems(){
mySelectedTrips.get().then((querySnapshot) {
querySnapshot.docs.forEach((snapshot) {
setState(() {
data = snapshot.data();
uid = snapshot['uid'];
description = snapshot['description'];
image = snapshot['image'];
});
});
});
}
Hi here is a short example how to create a pdf with one page.
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
class PdfCreator {
void createPdf(Snapshot snapshot) async {
final Document pdf = Document();
final page = Page(
pageFormat: PdfPageFormat.a4,
build: (Context context) {
return Column(
children: [
Text(snapshot.snapshot['description']),
Text(snapshot.snapshot['uid'].toString()),
Image(MemoryImage(snapshot['image'])),
],
);
},
);
pdf.addPage(page);
// Save file
final output = await getTemporaryDirectory();
var path = "${output.path}/test.pdf";
final file = File(path);
await file.writeAsBytes(await pdf.save());
}
}
You can enhance it and create one page per element in your foreach loop and and it to the pdf and so on.
Hint: if you want to use flutter widgets and pdf widgets in one file you can import pdf as p for example:
import 'package:pdf/widgets.dart' as p;
...
final flutterWidget = Text('abc');
final pdfWidget = p.Text('def');
I am trying to open PDF file using flutter_fullpdfview 1.0.12, i have the PDF file located under assets folder but somehow i am getting error unable to find file. I tried several options but none of them worked all return same error. Below are the functions i tried to load file and both of them failed with same error.
Future<File> copyAsset() async {
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
File tempFile = File('$tempPath/copy.pdf');
ByteData bd = await rootBundle.load('assets/jainaarti.pdf');
await tempFile.writeAsBytes(bd.buffer.asUint8List(), flush: true);
return tempFile;
}
Future<File> fromAsset(String asset, String filename) async {
// To open from assets, you can copy them to the app storage folder, and the access them "locally"
Completer<File> completer = Completer();
try {
var dir = await getApplicationDocumentsDirectory();
File file = File("${dir.path}/$filename");
var data = await rootBundle.load(asset);
var bytes = data.buffer.asUint8List();
await file.writeAsBytes(bytes, flush: true);
completer.complete(file);
} catch (e) {
throw Exception('Error parsing asset file!');
}
return completer.future;
}
It appears that the pdf library you are using is set up to use a system filepath to load the pdf. Unfortunately, this differs from the asset path that you have access to, and Flutter currently does not support the ability to get an assets system filepath at runtime. The only way I can find to use that library is to transfer the files to a known directory, and load from there. Rather than do this, I would recommend the native_pdf_view library, as it supports asset loading as well as full screen. You should be able to implement it as follows:
final pdfController = PdfController(
document: PdfDocument.openAsset('assets/copy.pdf'),
);
return Scaffold(
body: Center(
child: PdfView(
controller: pdfController,
)
),
);
-- EDIT --
To switch pages, if you want to start the viewer on a different page, just edit the initialPage in the pdfController
final pdfController = PdfController(
document: PdfDocument.openAsset('assets/copy.pdf'),
initialPage: 2
);
If you want to switch pages after the pdfView has been created, you can call jumpToPage() or animateToPage() from anywhere, provided you can get a reference to the pdfController, and that it and the pdfView have been instantiated.
return Scaffold(
body: Stack(
children: [
Center(
child: PdfView(
controller: pdfController,
)
),
RaisedButton(
child: Text("Page 2"),
onPressed: (){
pdfController.jumpToPage(2);
// -- or --
pdfController.animateToPage(2, duration: Duration(seconds: 1), curve: Curves.linear);
},
),
],
),
);
I'm trying on Postman. And it works
I want upload some image to rest-api using Package DIO Package ,
I'm new for this package (i'm use this package just for CRUD operation) and i'm got problem when upload image operation.
i'm already reading documentation and nothing see for upload images. I'm try this code(ref on documentation) and got some error :
error:FileSystemException
message :"Cannot retrieve length of file"
OSError (OS Error: No such file or directory, errno = 2)
"File: '/storage/emulated/0/Android/data/com.example.mosque/files/Pictures/scaled_IMG_20190815_183541.jpg'"
Type (FileSystemException)
message:FileSystemException: Cannot retrieve length of file, path = 'File: '/storage/emulated/0/Android/data/com.example.mosque/files/Pictures/scaled_IMG_20190815_183541.jpg'' (OS Error: No such file or directory, errno = 2)
DioErrorType (DioErrorType.DEFAULT)
name:"DioErrorType.DEFAULT"
Api.dart
Future uploadImage({dynamic data,Options options}) async{
Response apiRespon = await dio.post('$baseURL/mahasiswa/upload/',data: data,options: options);
if(apiRespon.statusCode== 201){
return apiRespon.statusCode==201;
}else{
print('errr');
return null;
}
}
View.dart
void uploadImage() async {
FormData formData = FormData.from({
"name_image": _txtNameImage.text,
"image": UploadFileInfo(File("$_image"), "image.jpg")
});
bool upload =
await api.uploadImage(data: formData, options: CrudComponent.options);
upload ? print('success') : print('fail');
}
_image is type FILE
I hope who expert with this package can help me with this code and suggest me for upload images.
Thanks.
Full View.dart Code
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:mosque/api/api_mosque.dart';
class UploadImage extends StatefulWidget {
#override
_UploadImageState createState() => _UploadImageState();
}
class _UploadImageState extends State<UploadImage> {
ApiHelper api = ApiHelper();
File _image;
TextEditingController _txtNameImage = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_left),
onPressed: () => Navigator.pop(context, false),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.file_upload),
onPressed: () {
uploadImage();
},
)
],
),
body: _formUpload(),
);
}
Widget _formUpload() {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: <Widget>[
TextField(
controller: _txtNameImage,
keyboardType: TextInputType.text,
decoration: InputDecoration(hintText: "Nama Image"),
maxLength: 9,
textAlign: TextAlign.center,
),
SizedBox(
height: 50.0,
),
Container(
child: _image == null
? Text('No Images Selected')
: Image.file(_image),
),
SizedBox(
height: 50.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Icon(Icons.camera),
onPressed: () => getImageCamera(),
),
SizedBox(
width: 50.0,
),
RaisedButton(
child: Icon(Icons.image),
onPressed: () => getImageGallery(),
)
],
)
],
),
);
}
void uploadImage() async {
FormData formData = FormData.from({
"name_image": _txtNameImage.text,
"image": UploadFileInfo(File("$_image"), "image.jpg")
});
bool upload =
await api.uploadImage(data: formData, options: CrudComponent.options);
upload ? print('success') : print('fail');
}
getImageGallery() async {
var imageFile = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = imageFile;
});
}
getImageCamera() async {
var imageFile = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image = imageFile;
});
}
}
In Dio latest version, UploadFileInfo method has been replaced by MultipartFile class. And here the way how to use to post image, video or any file:
Future<String> uploadImage(File file) async {
String fileName = file.path.split('/').last;
FormData formData = FormData.fromMap({
"file":
await MultipartFile.fromFile(file.path, filename:fileName),
});
response = await dio.post("/info", data: formData);
return response.data['id'];
}
Even this question is asked a while ago, I believe the main issue is the size of image especially with Laravel.Flutter Image Picker library offers some functionalities to reduce the size of Image, I solved it with bellow steps:
Create a method to get the Image, I am using Camera to Capture the photo
Future getImage() async {
File _image;
final picker = ImagePicker();
var _pickedFile = await picker.getImage(
source: ImageSource.camera,
imageQuality: 50, // <- Reduce Image quality
maxHeight: 500, // <- reduce the image size
maxWidth: 500);
_image = _pickedFile.path;
_upload(_image);
}
Create _upload method to upload the photo, I am using Dio package Dio Package
void _upload(File file) async {
String fileName = file.path.split('/').last;
FormData data = FormData.fromMap({
"file": await MultipartFile.fromFile(
file.path,
filename: fileName,
),
});
Dio dio = new Dio();
dio.post("http://192.168.43.225/api/media", data: data)
.then((response) => print(response))
.catchError((error) => print(error));
}
On the server side, I am using Laravel Laravel, I handle the request as follow
public function store(Request $request)
{
$file = $request->file('file');
$extension = $file->getClientOriginalExtension();
$fullFileName = time(). '.'. $extension;
$file->storeAs('uploads', $fullFileName, ['disk' => 'local']);
return 'uploaded Successfully';
}
In the latest version of Dio :
It should look like this.
String fileName = imageFile.path.split('/').last;
FormData formData = FormData.fromMap({
"image-param-name": await MultipartFile.fromFile(
imageFile.path,
filename: fileName,
contentType: new MediaType("image", "jpeg"), //important
),
});
If without this line.
contentType: new MediaType("image", "jpeg")
Maybe it will cause an error: DioError [DioErrorType.RESPONSE]: Http status error [400] Exception
And get MediaType in this package: http_parser
The following code uploads multiple image files from a dio client to a golang server.
dioclient.dart
FormData formData = FormData.fromMap({
"name": "wendux",
"age": 25,
"other" : "params",
});
for (File item in yourFileList)
formData.files.addAll([
MapEntry("image_files", await MultipartFile.fromFile(item.path)),
]);
Dio dio = new Dio()..options.baseUrl = "http://serverURL:port";
dio.post("/uploadFile", data: formData).then((response) {
print(response);
}).catchError((error) => print(error));
golangServer.go
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func uploadFile(w http.ResponseWriter, r *http.Request) {
err := r.ParseMultipartForm(200000)
if err != nil {
fmt.Fprintln(w, err)
return
}
formdata := r.MultipartForm
files := formdata.File["image_files"]
for i, _ := range files {
file, err := files[i].Open()
defer file.Close()
if err != nil {
fmt.Fprintln(w, err)
return
}
out, err := os.Create("/path/to/dir/" + files[i].Filename)
defer out.Close()
if err != nil {
fmt.Fprintf(w, "Unable to create the file for writing. Check your write access privilege")
return
}
_, err = io.Copy(out, file)
if err != nil {
fmt.Fprintln(w, err)
return
}
fmt.Fprintf(w, "Files uploaded successfully : ")
fmt.Fprintf(w, files[i].Filename+"\n")
}
}
func startServer() {
http.HandleFunc("/uploadFile", uploadFile)
http.ListenAndServe(":9983", nil)
}
func main() {
fmt.Println("Server starts!")
startServer()
}
I have found a solution, where I am uploading file a specific directory which is generated different camera package which requires file path to save jpg file in the provided path.
and I was fetching file name with path and passing to
DIO package
which was giving file length issue, to I have implemented below steps to solve the issue
get File Name With Full Path from directory
create a File from the Path
File(directoryFilePathWithExtension);
and pass File.path to the dio package
MultipartFile.fromFile(
File(directoryFilePathWithExtension).path,
filename: DateTime.now().toIso8601String(),
)
Use UploadFileInfo.fromBytes if you're working with memory images (The error message above shows that your file is invalid and doesn't exist).
Hi there are many issue in file upload
try in android Api 21 because it did not have android permissions if api is working in android api 21 then it wil also work on above versions.
you might not able to get the file in above android version
you just need
FormData formData = FormData.fromMap({
"av_document": await MultipartFile.fromFile(_filePath,filename:
_fileName),
});
to upload any file or image to server and one more thing to note
_filePaths = await FilePicker.getMultiFilePath(type: _pickingType,
fileExtension: _extension);
_fileName = _filePath.split('/').last
by using this process u can upload file or image to server
I am using
dio: ^4.0.6 (for uploading)
flutter_native_image: ^0.0.6+1 (for reducing image size)
to reduce file size
File? compressedFile = profileImage.value == null
? null
: await FlutterNativeImage.compressImage(
profileImage.value?.path ?? '',
quality: 20,
percentage: 60);
dio formData map
var formData = dio.FormData.fromMap({
"name": input['name']!.text,
"profile_pic": await dio.MultipartFile.fromFile(compressedFile.path),
"birth_date": input['dob']!.text,})
request ->
response = await _dio.post(url, data: formData);