Reputation: 21
I'm building an app using Ionic7 and Capacitor5 and Vue3 to list and upload invoices as PDF, my app has 3 options:
I'm having troubles with the 3rd option only
I have a function responsible of choosing photos from gallery, and another function responsible of taking photo, and a function which take photos and merge them in a PDF file using PDF-lib library and call uploading function.
when choosing photos from gallery, the whole process succeed and the pdf is uploaded, But when taking photos and click upload, Symfony Backend Server returns the following error:
{ ...
"class": "RuntimeException",
"file": "\/var\/www\/html\/wms-dev\/vendor\/guzzlehttp\/psr7\/src\/Utils.php",
"line": 389,
"status_text": "Internal Server Error",
"message": "Unable to open \"\" using mode \"r\": Path cannot be empty",
...
}
Here are my functions:
Selecting photos from gallery:
async selectImagesFromGallery() {
try {
const result = await Camera.pickImages({
quality: 90,
width: 800,
height: 800,
limit: 100 // Adjust the limit as needed
});
console.log("selected Images ===>", result)
this.photos = result.photos.map(photo => {
return {
...photo,
selected: false
};
});
console.log("this.photos ====>", this.photos)
this.togglePhotosModal()
} catch (error) {
console.error('Error selecting photo:', error);
} finally{
this.loading = false
}
},
Taking photo using camera:
async prendrePhoto(){
this.isUsingCamera = true
const photo = await Camera.getPhoto({
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
quality: 100
})
console.log("Photo taken after blob ===>", await this.blobUrlToFile(photo.webPath, `image.${photo.format}`, `image/${photo.format}`))
const photoWithSelected = {
...photo,
selected: true
}
this.photos.push(photoWithSelected)
if(!this.isPhotosModalOpen) this.togglePhotosModal()
console.log("Photos taken ===>", this.photos)
},
Merging photos in pdf and send it:
async createPdfFromPhotosAndUpload() {
this.sendingLoading = true
try {
const selectedPhotos = this.photos.filter((photo: any) => photo.selected);
console.log("length of selectedPhotos Array ===>", selectedPhotos.length)
if (selectedPhotos.length === 0) {
console.log('No photos selected');
return;
}
const pdfDocs: Uint8Array[] = [];
for (const photo of selectedPhotos) {
const pdf = new jsPDF();
const img = new Image();
img.src = photo.webPath;
await new Promise<void>(resolve => {
img.onload = () => {
const imgWidth = 180;
const imgHeight = (img.height * imgWidth) / img.width; // Maintain aspect ratio
pdf.addImage(img, 'JPEG', 15, 15, imgWidth, imgHeight);
// Convert ArrayBuffer to Uint8Array
const pdfBytes = new Uint8Array(pdf.output('arraybuffer'));
pdfDocs.push(pdfBytes);
resolve();;
};
});
}
// Step 2: Merge all PDFs
const mergedPdf = await PDFDocument.create();
for (const pdfBytes of pdfDocs) {
const pdf = await PDFDocument.load(pdfBytes);
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
copiedPages.forEach(page => mergedPdf.addPage(page));
}
const mergedPdfBytes = await mergedPdf.save();
// Step 3: Save the merged PDF
const pdfDocument = new File([mergedPdfBytes], 'mergedDocument.pdf', { type: 'application/pdf' });
console.log("pdfDocument ===>", pdfDocument)
const res = await this.uploadDocument(pdfDocument)
if(res){
this.photos = this.photos.filter((photo: any) => !photo.selected)
this.showToast('Document Envoyé !', 2000, 'success', planeIcon)
if(!this.photos.length) this.togglePhotosModal()
}
} catch (error) {
console.error("error creating pdf !!", error)
} finally {
this.sendingLoading = false
}
},
I have searched all over the internet and related issue but couldn't resolve it, I'll pleased if you help guys
Upvotes: 1
Views: 54