Jethro Hazelhurst
Jethro Hazelhurst

Reputation: 3285

Call a method inside an object with setInterval is not working

I am trying to poll my server using a method inside my object using the setInterval() function. The code looks like this:

(function(){

    var teacherZone = {

        init: function(){
            this.cacheDOM();
            this.bindEvents();
            this.pollServer(); // get the list of lessons
        },
        cacheDOM: function(){
            this.$showLessons     = $('#showLessons');
            this.$lessonsTemplate = $('#lessonsTemplate');
        },
        bindEvents: function(){

        },
        pollServer: function(){
            alert('Polled');
        }

    }

    teacherZone.init();
    setInterval(teacherZone.pollServer(), 1000)
})();

This calls the alert() twice but then no more. Not sure where I am going wrong here.

How do I repeatedly call a method inside an object at a set interval?

UPDATED CODE:

(function(){

    var teacherZone = {

        interval: 5000,

        init: function(){
            this.cacheDOM();
            this.bindEvents();
            setInterval(function(){
                teacherZone.pollServer(); // get the list of lessons
            }, teacherZone.interval);
        },
        cacheDOM: function(){
            this.$showLessons     = $('#showLessons');
            this.$lessonsTemplate = $('#lessonsTemplate');
        },
        bindEvents: function(){

        },
        pollServer: function(){
            alert('Polled');
            // data = {
            //     name: 'John'
            // };
            // this.$showLessons.html(Mustache.render(this.$lessonsTemplate.html(), data));
        }

    }

    teacherZone.init();
    teacherZone.pollServer();

})();

Upvotes: 3

Views: 1302

Answers (4)

ibrahim mahrir
ibrahim mahrir

Reputation: 31692

You have to pass a reference to the function to setInterval like this:

setInterval(teacherZone.pollServer, 1000);

If you want to be able to use this inside the function pollServer, then you'll have, either, to bind this to your object using bind like this:

setInterval(teacherZone.pollServer.bind(teacherZone), 1000);

or wrap the call to pollServer inside an anonimous function like this:

setInterval(function() {
    teacherZone.pollServer();
}, 1000);

because if you don't then this will be the parent object of setInterval which is the window object.

Edit:

You can do it in simple way, in case you have to create more instances of teacherZone or rename the object teacherZone you won't need to rename all the lines that depends on it. Just simply store the value of this outside setInterval (read about closures) like this:

init: function(){
    this.cacheDOM();
    this.bindEvents();
    var that = this;       // store this here so it will be accessible inside setInterval
    setInterval(function(){
        that.pollServer(); // use that here (because this will be the window object here so we use that because it holds a reference to the object we want)
    }, this.interval);     // no need to use that here just this will suffice (because here we are inside init not inside the callback of setInterval)
},

Now you can rename the object teacherZone without worrying!

Upvotes: 2

TechVision
TechVision

Reputation: 269

You can also try this way :

(function(){ 
   $.teacherZone = { 
    init: function(){
        this.cacheDOM();
        this.bindEvents();
        this.pollServer(); 
    },
    cacheDOM: function(){
        this.$showLessons     = $('#showLessons');
        this.$lessonsTemplate = $('#lessonsTemplate');
    },
    bindEvents: function(){

    },
    pollServer: function(){
        console.log('Polled');
    } 
  } 
 $.teacherZone.init(); 
 setInterval($.teacherZone.pollServer, 1000);

})(); 

Upvotes: 1

Abhinav Galodha
Abhinav Galodha

Reputation: 9878

You need a function reference instead of calling the function.

Change From: setInterval(teacherZone.pollServer(), 1000)
To" setInterval(teacherZone.pollServer, 1000)

(function(){

    var teacherZone = {

        init: function(){
            this.cacheDOM();
            this.bindEvents();
            this.pollServer(); // get the list of lessons
        },
        cacheDOM: function(){
            this.$showLessons     = $('#showLessons');
            this.$lessonsTemplate = $('#lessonsTemplate');
        },
        bindEvents: function(){

        },
        pollServer: function(){
            alert('Polled');
        }

    }

    teacherZone.init();
    setInterval(teacherZone.pollServer, 1000)
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386560

You need to remove the parenthesis, because you call the function immediately and do not hand over the function.

setInterval(teacherZone.pollServer, 1000)
//                               ^^

Upvotes: 4

Related Questions