Reputation: 1992
I am trying to render a series of image thumbnails based on images that I drag onto the screen.
My data looks like this:
data() {
return {
files: [File1, File2, File3]
}
}
...where each File
is a blob
.
Here is my computed
property, that should just return me each File
blob
s result
thumbnails() {
return files.map(file => {
let reader = new FileReader();
reader.readAsDataURL(file);
return reader.result
})
}
I then try to render on screen as:
<ul>
<li v-for="thumbnail in thumbnails>
<img :src="thumbnail">
</li>
</ul>
It doesn't work.
What is extremely interesting, however, is that if I insert a breakpoint in the files.map(...)
, it does work! What am I missing?
Upvotes: 1
Views: 737
Reputation: 10076
What am I missing?
The fact that FileReader.readAsDataURL()
method is asynchronous.
I'd recommend you to rethink your flow, or you can use vue-async-computed
package.
Using it you can write it liked this:
{
asyncComputed: {
thumbnails() {
return Promise.all(this.files.map((file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
// handle success
reader.addEventListener('load', () => {
resolve(reader.result);
}, false);
// handle error
reader.addEventListener('error', () => {
reject();
}, false);
// reading file
reader.readAsDataURL(file);
});
}));
},
}
}
Don't forget that until Promise.all
is resolved the thumbnails
will be null
, so you should add check for that to your template.
Upvotes: 4