Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't get setInterval function to call another function using this.function_name in javascript

Tags:

javascript

I have a function inside a object that sets up a interval that calls another function but when ever that interval function is called it gives my a error saying Uncaught TypeError: Object [object Window] has no method

here is my code that I'm trying to understand.

function test2() {
this.timer;

this.say = function(){
    console.log("hi");
}

this.start = function() {
    //starts the interval function
    this.timer = setInterval(this.loop, 1000)
}

this.loop = function() {
    //runs every 1 second  
    this.say(); //gives error -- Uncaught TypeError: Object [object Window] has no method 'say'
}
}

var test = new test2();
test.start();

Thank you for your help!

like image 897
Justin Avatar asked Sep 08 '25 11:09

Justin


2 Answers

When setInterval() fires, the context is the global context (e.g. window), not your object. To call a method on your object and have the value of this set appropriately in that method call, you need a separate function where you can call the method on your actual object like this:

this.start = function() {
    //starts the interval function
    var self = this;
    this.timer = setInterval(function() {
        self.loop();
    }, 1000)
}

FYI, it is very common when using an asynchronous functions like timers or ajax to save the context this into a local variable so it can then be referenced from the embedded callback function even when this is different in the callback function (as in your example). This is a common design pattern.

like image 67
jfriend00 Avatar answered Sep 10 '25 01:09

jfriend00


I had a unique solution to this one. I got around it by making a function that calls my object method:

const globalSet = new globals();

function ut(){
    globalSet.updateToasts();
}

setInterval(ut,15000);

It seems to have tricked JS into doing what I wanted.

like image 26
James Reinsch Avatar answered Sep 10 '25 03:09

James Reinsch