Reputation: 1475
I have created a Vue component called imageUpload
and passed a property as v-model like so:
<image-upload v-model="form.image"></image-upload>
and within the imageUpload
component I have this code
<input type="file" accept="images/*" class="file-input" @change="upload">
upload:(e)=>{
const files = e.target.files;
if(files && files.length > 0){
console.log(files[0])
this.$emit('input',files[0])
}
}
and I receive this error:
Uncaught TypeError: _this.$emit is not a function
Thanks
Upvotes: 27
Views: 53390
Reputation: 5692
This error surfaces if $emit is not on the current context/reference of this
, perhaps when you're in the then
or catch
methods of a promise. In that case, capture a reference to this
outside of the promise to then use so the call to $emit
is successful.
<script type="text/javascript">
var Actions = Vue.component('action-history-component', {
template: '#action-history-component',
props: ['accrual'],
methods: {
deleteAction: function(accrualActionId) {
var self = this;
axios.post('/graphql',
{
query:
"mutation($accrualId: ID!, $accrualActionId: String!) { deleteAccrualAction(accrualId: $accrualId, accrualActionId: $accrualActionId) { accrualId accrualRate name startingDate lastModified hourlyRate isHeart isArchived minHours maxHours rows { rowId currentAccrual accrualDate hoursUsed actions { actionDate amount note dateCreated } } actions {accrualActionId accrualAction actionDate amount note dateCreated }} }",
variables: {
accrualId: this.accrual.accrualId,
accrualActionId: accrualActionId
}
}).then(function(res) {
if (res.data.errors) {
console.log(res);
alert('errors');
} else {
self.$emit('accrualUpdated', res.data.data.deleteAccrualAction);
}
}).catch(function(err) {
console.log(err);
});
}
}
});
Upvotes: 6
Reputation: 82469
Do not define your method with a fat arrow. Use:
upload: function(e){
const files = e.target.files;
if(files && files.length > 0){
console.log(files[0])
this.$emit('input',files[0])
}
}
When you define your method with a fat arrow, you capture the lexical scope, which means this
will be pointing to the containing scope (often window
, or undefined
), and not Vue.
Upvotes: 42
Reputation: 1714
You can write the method in short using upload(e) {
instead of upload:(e)=>{
to make this point to the component.
Here is the full example
watch: {
upload(e) {
const files = e.target.files;
if(files && files.length > 0) {
console.log(files[0]);
this.$emit('input',files[0]);
}
}
}
Upvotes: 1