Reputation: 1379
I cannot make the timer to call my class method. This works fine:
MyInput = class {
constructor(params) {
let input = params.input;
input.addEventListener('focus', this.setTimer);
}
setTimer() {
this.timer = window.setInterval(() => {
console.log('yay');
}, 300);
}
};
but this:
MyInput = class {
constructor(params) {
let input = params.input;
input.addEventListener('focus', this.setTimer);
}
setTimer() {
this.timer = window.setInterval(this.lookupOptions, 300);
}
lookupOptions() {
console.log('yay');
}
};
doesn't call the lookupOptions
method but instead, my developer tools in the browser stops debugger every 300ms (checked with different values - always in synch with the timer). After a while, it opens some strange file VM[number]
with different numbers. I have no idea why it doesn't work. When I used timer outside the class in the same way it worked fine it seems like some problem with calling the class method but I cannot figure out what the problem might be. Could you please help?
Upvotes: 0
Views: 59
Reputation: 20934
When setInterval
calls the function it changes the context of this
to the scope of the setInterval
, which would be the window
object.
Scope the callback in setInterval
by wrapping it with an arrow function expression. This prevents the scope from being changed.
MyInput = class {
constructor(params) {
let input = params.input;
input.addEventListener("focus", () => {
this.setTimer();
});
}
setTimer() {
this.timer = window.setInterval(() => {
this.lookupOptions();
}, 300);
}
lookupOptions() {
console.log("yay");
}
}
Or use the .bind()
method, that is present on each function object to manually set the scope for this
.
MyInput = class {
constructor(params) {
let input = params.input;
const boundSetTimer = this.setTimer.bind(this)
input.addEventListener("focus", boundSetTimer);
}
setTimer() {
const boundLookupOptions = this.lookupOptions.bind(this)
this.timer = window.setInterval(boundLookupOptions, 300);
}
lookupOptions() {
console.log("yay");
}
}
Or use the experimental public fields, which do somewhat the same as arrow function expressions, but as a method of an object.
MyInput = class {
constructor(params) {
let input = params.input;
input.addEventListener("focus", this.setTimer);
}
setTimer = () => {
this.timer = window.setInterval(this.lookupOptions, 300);
}
lookupOptions = () => {
console.log("yay");
}
}
Upvotes: 2