The following small count down application cause Uncaught TypeError: Cannot read property 'counter' of undefined at the timing of evaluation of this.counter.
<template>
<v-app>
<v-content>
Redirect after {{counter}} sec.
</v-content>
</v-app>
</template>
<script>
/* eslint-disable no-console */
export default {
name: 'App',
components: {
},
mounted() {
this.countdown();
},
created() {
},
methods: {
countdown: () => {
setTimeout(() => {
if (--this.counter <=0){
location.href=this.$redirectURL;
} else {
this.countdown();
}
}, 1*1000);
}
},
data: () => ({
counter: 5,
}),
};
</script>
Uncaught TypeError: Cannot read property 'counter' of undefined as follows:
I have no idea why coutner is evaluated as undefined despite I'm using arrow function, which means the scope of "this pointer" must be lexical. Thank you for your suggestions!
The countdown
function is an arrow function, which means that the this
inside it is inherited from the outer scope. The same is true for the setTimeout
callback. So, here:
export default {
// ...
methods: {
countdown: () => {
setTimeout(() => {
if (--this.counter <=0){
location.href=this.$redirectURL;
} else {
this.countdown();
}
}, 1*1000);
}
},
// ...
}
this
refers to the this
at the top level of the module, which is undefined
in your setup.
You want this
to refer to the current instance instead: when calling countdown
, it should capture the new this
value (of the instance), rather than inheriting the this
of the outer scope. So, change:
countdown: () => {
to
countdown() {
or to
countdown: function() {