I encountered an issue, that maybe some of you have answer for. I have a dashboard-like app running on MEVN Stack. I want the user to be able to upload his image and store it in backend server, because as I understood, it is not possible to upload to VueJS project public folder directly.
So I found a way to upload it thanks to some post I found here. But I cannot find a way back. My image is store on my backend server and I want to get it using axios in blob form and display it in VueJS. It should be pretty simple but there something I may missed.
First I get the name of my image file and send it like this with Express:
res.sendfile(path.join(__dirname,"../../images/societies/",result.img_link));
I also return a default image url if there is no image, which works fine, but not the fetched images. The problem is I cannot access the image directly using URL, it is not accessible. So I have to find a way to get it as a blob I guess and display it.
Here is the code I use to get my Image in frontend, VueJS (script part):
getSocietyImage(society) {
if(society.image){
this.$http
.get(this.apiUrl + "society/getImg/" + society.id)
.then(image => {
return image.data
})
.catch(err => {
console.log(err)
})
}else{
return this.basicImgUrl
}
}
Here is the code in the template part which is a part of a v-for directive:
<img
:src="getSocietyImage(society)"
alt="content-img"
class="responsive card-img-top"
/>
Below is what I get from the request from a console.log():
Thanks everyone for your help!
You shouldn't bind to methods. The method will run every time the template is re-rendered, which means whenever some relevant data changes.
Template rendering is synchronous, which means you can't bind to an async method at all. You should use a lifecycle hook (this example uses a URL):
new Vue({
el: "#app",
data() {
return {
myimage: null
}
},
methods: {
async getImage() {
// Just a mockup of returning something async
return await 'https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.svg';
}
},
async created() {
this.myimage = await this.getImage();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<img :src="myimage">
</div>
You can either send back the raw binary or convert to base 64
blob
)Server
res.sendFile(file); // Send raw binary
Browser
<img :src="myimage" />
async created() {
const { data } = await this.getImage(); // Binary from server
const blob = new Blob([data]);
this.myimage = URL.createObjectURL(blob);
}
Note: Don't forget to clean up with URL.revokeObjectURL
Or you could convert the binary to Base64 with Express first (but Base64 takes up about ~33% more bandwidth than binary):
Server
const bitmap = fs.readFileSync(file);
const base64 = new Buffer.from(bitmap).toString("base64");
res.send(base64); // Send base64 instead of the raw file binary
Browser
<img :src="myimage" />
async created() {
const { data } = await this.getImage(); // base64 data from server
this.myimage = 'data:image/png;base64,' + data;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With