I implemented the Vue Dropzone plugin and I'm able to upload images, send a request to my API to store the image and make requests to show the image. I'm using the dataURL attribute with Base64 data to decode it back to an image.
However, when I upload a PDF file or another document, there is no dataURL attribute. How can I save the uploaded PDF to the local storage of my Vue app? I currently use the default url https://httpbin.org/post. Should I use my own API request as the url instead of making a separate axios call in the afterComplete(file) method?
Hi @peeredNL
Can you show your how you've configured the component?
If I understand correctly you want to save the pdf in localstorage of the browser rather than on the server, if that's the case your use case has nothing really to do with vue-dropzone, it's just about working out the js code for reading a pdf file object and working out how to store and then re-read it...
The configuration of the component is as follows:
dropOptions: {
url: "https://httpbin.org/post",
maxFiles: 1,
addRemoveLinks: true,
maxFilesize: 5,
uploadMultiple: false,
}
In the @vdropzone-complete="afterComplete" method, I send the dataURL and name attributes of the file variable to the API of my application. The API adds a new record in the database regarding the file and stores the file at the server. As long as the uploaded file is an image, this works fine. When I upload a PDF or any other document, there is no dataURL attribute in the returned file variable.
Sorry but I dont think this is anything to do with vue-dropzone.
You either need to find a way to store the pdf's on a server as a file, rather than a db record, your db record could point to the filepath to the pdf file.
Or you need to find a way to turn the contents of the pdf into something you can store in a db, this either needs to be done in js, or you could do it using whatever server side language you're using.
I already found a way to store the images on the server (decoding the base64 attribute as returned by vue-dropzone). The database record only contains a filepath, filetype and filename. However, when I try to upload a PDF file, the dropzone does not return a base64 attribute, so I can't decode it.
You should be sending the actual pdf, your url option should be your service endpoint, not the example one
Hello, i have the same problem with @peeredNL. @vdropzone-file-added gives an image's dataURL in the file object which i use to upload images. But in the case of pdfs there is no dataURL.
I found a solution for anyone interested. You can get pdf file's dataURL this way:
var fileReader = new FileReader();
var base64;
fileReader.onload = (fileLoadedEvent) => {
base64 = fileLoadedEvent.target.result;
// base64 is the dataURL
this.pdfFile.dataURL= base64;
<!---(your own code here)-->
};
fileReader.readAsDataURL(this.pdfFile);
Thanks for sharing @Barous-Anastasios
Hi @Barous-Anastasios, I'm sorry, but when do you call your fileReader? Is there any event on vue-dropzone that is called when you select a PDF to upload? Could you please post a full exemple of using your sulution with vue-dropzone?
Hello @victorpinheiro,
Something like this would work using a setTimeout() or SetInterval() , though im pretty sure its not the most rational approach.
<script>
new Vue({
el: '#app',
components: {
vueDropzone: vue2Dropzone
},
data: {
dropzoneOptions: {
url: 'https://httpbin.org/post',
thumbnailWidth: 150,
maxFilesize: 0.5,
headers: { "My-Awesome-Header": "header value" }
},
pdfFile:'',
},
methods:{
handleFileAdding(file){
this.pdfFile = file;
},
getDataURL(){
var fileReader = new FileReader();
var base64;
fileReader.onload = (fileLoadedEvent) => {
base64 = fileLoadedEvent.target.result;
this.pdfFile.dataURL= base64;
};
fileReader.readAsDataURL(this.pdfFile);
// Checks every second for the dataURL.
var checkIfReady = setInterval(()=>{
// If there is it logs it.
if(fileReader.result){
console.log(fileReader.result)
// USE the DATAURL
clearInterval(checkIfReady);
}
// Stops checking after 10 seconds.
setTimeout(()=>{
clearInterval(checkIfReady);
}, 10000)
},1000);
}
}
})
</script>
</head>
<body>
<div id="app">
<vue-dropzone @vdropzone-file-added="handleFileAdding" ref="myVueDropzone" id="dropzone" :options="dropzoneOptions"></vue-dropzone>
<button @click="getDataURL">SHOW DATA URL ON CONSOLE</button>
</div>
</body>
Most helpful comment
Hello @victorpinheiro,
Something like this would work using a setTimeout() or SetInterval() , though im pretty sure its not the most rational approach.