Reputation: 37
I’m just starting to learn Quasar (and Vue). I’m trying to encode a picture into a Base64 and save to MongoDB. Undermentioned code works for the component but I can’t redo it for the component . I will be thankful for any help
<q-uploader v-model="image" @change="encodeToBase64" />
<q-btn type="btn" @click="sendPhoto">Save photo in mongo and go next page</q-btn>
methods: {
encodeToBase64 (event) {
event.preventDefault()
const file = event.target.files[0]
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
const reader = new FileReader()
reader.onload = event => {
const img = new Image()
img.onload = () => {
if (img.width > MAX_WIDTH) {
canvas.width = MAX_WIDTH
canvas.height = (MAX_WIDTH * img.height) / img.width
} else {
canvas.width = img.width
canvas.height = img.height
}
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
this.image = canvas.toDataURL('image/png').replace(/^data:image\/(png|jpg);base64,/, '')
console.log('RESULT/png', this.image)
}
img.src = event.target.result
console.log('RESULT!', img.src)
}
reader.readAsDataURL(file)
}
}
sendPhoto (event) {
event.preventDefault()
this.$store.dispatch('image/create', {account_id: this.account_selected, image: this.image})
.then((res) => {
this.$router.push({'path': '/nextReadings/' + res._id})
})
.catch((err) => {
err.message = 'Error message'
this.errorHandler(err.message)
})
}
Upvotes: 1
Views: 3109
Reputation: 36
Here is how you can get a file in q-uploader into a base64 string. From there you should be able to figure out how to insert this string into your database.
1) Add a ref name to q-uploader. (I am using "files")
<q-uploader ref="files" label="My Label" :additional-fields="[{name: 'name', value: 'value'}]" multiple/>
2) You can now get the files in q-uploader anytime by using
this.$refs.files.files
3) Create the following two functions. This is the most concise and simple way that I have found to convert a javascript File into base64.
async encodeToBase64(files) {
var attach = [];
var reader = [];
// loop through each of the files in q-uploader
for (let i = 0; i < files.length; i++) {
attach[i] = await this.singleFileToBase64(i, files, reader)
}
// returns an array of all the files in base64 format
return attach;
},
singleFileToBase64(i, files, reader) {
reader[i] = new FileReader();
// read the file into a base64 format
reader[i].readAsDataURL(files[i]);
return new Promise((resolve, reject) => {
reader[i].onerror = () => {
reader[i].abort();
reject("Insert error message here")
};
// return the base 64 string
reader[i].onload = function () {
resolve(reader[i].result);
};
})
},
Note: Using async, await and promises are key here. Otherwise reader.onload may not have run before you end up trying to use the output.
4) Call your function using the code from step 2
encodeToBase64(this.$refs.files.files)
Note: I have written this to reflect there being multiple files in q-uploader since that can be tricky to figure out with async, await and promises.
Note: I could probably get rid of the reader array and just declare it as a normal reader in singleFileToBase64
method... but I have not tested that.
Upvotes: 2