Reputation: 595
EDIT
This answer does solve a problem on running two different functions back to back. Nevertheless, my question deals specifically with the behavior of a file handling input and the moment in which to chain a second event (solved by the second example in @Igor 's answer).
QUESTION
I have a file upload Vue component which works perfectly fine. The improvement I would like to make is for it to work on "one click", meaning the upload()
method should be triggered in response to the createImage()
finishing. How would I do that?
<template>
<div>
<div>
<label>Image:</label>
<img :src="(image) ? image : tempImage" class="img-fluid">
<div class="custom-file">
<input type="file" v-on:change="onFileChange" class="custom-file-input"
:class="{ 'border-0':image }">
<label class="custom-file-label" for="customFile">
{{ filename ? filename : 'Choose pic' }}
</label>
</div>
</div>
<div>
<button class="btn btn-success btn-block"
:disabled="!image"
@click.prevent="upload">
Upload
</button>
</div>
</div>
</template>
<script>
export default{
props: ['tempImage'],
data(){
return {
image: '',
filename: ''
}
},
methods: {
onFileChange(e) {
let files = e.target.files || e.dataTransfer.files;
this.$parent.uploading = true;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file) {
let reader = new FileReader();
let vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
vm.filename = file.name;
},
upload(){
console.log(this.image);
axios.post('/api/upload',{image: this.image}).then(res => {
if( !res.data.errors ){
this.$parent.tempData.image = res.data.src;
this.$parent.uploading = false;
} else {
console.log(res.data.errors);
}
});
}
}
}
</script>
Upvotes: 0
Views: 1440
Reputation: 809
What about calling upload()
from createImage()
?
createImage(file) {
let reader = new FileReader();
let vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
vm.filename = file.name;
this.upload();
};
reader.readAsDataURL(file);
}
Or passing upload()
as a callback:
onFileChange(e) {
let files = e.target.files || e.dataTransfer.files;
this.$parent.uploading = true;
if (!files.length)
return;
this.createImage(files[0], this.upload);
},
createImage(file, callback) {
let reader = new FileReader();
let vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
vm.filename = file.name;
if (callback) callback();
};
reader.readAsDataURL(file);
}
Upvotes: 2
Reputation: 3565
You start off by creating a variable isUploading
with an initial value of false
. Then in your method upload
you first check if the isUploading
variable is false, if it is false, start upload, otherwise, either do nothing or inform the user that the page is still uploading image.
The code could look like this:
var isUploading = false;
export default {
// ...
upload() {
// If not uploading anything start the upload
if (!isUploading) {
isUploading = true;
console.log(this.image);
axios.post('/api/upload', {
image: this.image
}).then(res => {
if (!res.data.errors) {
this.$parent.tempData.image = res.data.src;
this.$parent.uploading = false;
} else {
console.log(res.data.errors);
}
});
} else {
// Do other stuff here
}
}
// ...
}
Upvotes: 0