Reputation: 3439
I am using vue.js in this case but I guess it would apply in plain JS too. The problem is that when I am in a function that is in another function I am having to call variables by their full path like - Object.variable instead of this.variable. Is there a way to use this.timer, this.pages instead of TVComponent.pages etc.
const TVComponent = new Vue ({
el: '.tvContent',
data:
{
current_page: 0,
timer: 0,
pages: [
{ page: '/', interval: 10 },
{ page: 'tv/calls', interval: 10 },
{ page: 'tv/general', interval: 10 }
]
},
methods:
{
tvTimer()
{
setInterval(function() {
TVComponent.timer++;
if (TVComponent.timer == TVComponent.pages[TVComponent.current_page].interval) {
console.log('it is time!!');
}
console.log(TVComponent.pages[TVComponent.current_page].page);
}, 1000);
},
})
Upvotes: 4
Views: 747
Reputation: 3757
This is because setInterval()
this
object is not same as vue.js this
, since they have different scopes.
Try to assign this
object to new variable before entering the problematic function's scope.
let self = this;
tvTimer()
{
setInterval(function() {
self.timer++;
if (self.timer == self.pages[self.current_page].interval) {
console.log('it is time!!');
}
console.log(self.pages[self.current_page].page);
}, 1000);
},
See: https://developer.mozilla.org/en-US/docs/Glossary/Scope
Upvotes: 0
Reputation: 23968
Classic problem of this
being not what you expect in a function
A. bind it
methods:
{
tvTimer()
{
setInterval(function() {
// ...
}.bind(this), 1000);
},
})
B. use a closure
methods:
{
tvTimer()
const _this = this
{
setInterval(function() {
_this.timer ...
}, 1000);
},
})
C. use an arrow function
methods:
{
tvTimer()
{
setInterval(() => {
this.timer ...
}, 1000);
},
})
This is one of those things one has to really understand about JS in order to not fall for it over and over in different places. I suggest this ebook:
https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch2.md#this-identifier
Upvotes: 2
Reputation: 7188
The function you pass to setInterval
receives its own context, however if you use an arrow function it will use the current context instead, and ignore the one given by setInterval
.
setInterval(() => { ... }, 1000)
Upvotes: 1
Reputation: 41
I think you have to bind it in this context. We do it this way in React classess.
Upvotes: -1