This question already has answers here:
Pass correct "this" context to setTimeout callback?
(6 answers)
Closed 8 years ago.
I am having trouble calling methods in a setInterval... Here is a snippet of my code...
var example = function(){
this.animate = function(){
console.log("Animate.");
}
this.updateTimer = function(){ // This is being called...
this.timer = setInterval(function(){
this.animate(); // A "Undefined Is Not A Function" error is being thrown here.
}, 1);
}
}
USE BIND (as #torazaburo said)
maybe best-practice
http://jsfiddle.net/rnrlabs/Lnmex1y7/
var example = function(){
this.animate = function(){
console.log("Animate.");
}
this.updateTimer = function() { // This is being called...
this.timer = setInterval(this.animate.bind(this), 1);
}
}
OR.. USE A CLOSURE
http://jsfiddle.net/rnrlabs/zk6hdnf2/
var example = function(){
var self = this; // this creates a closure
this.animate = function(){
console.log("Animate.");
}
this.updateTimer = function(){
this.timer = setInterval(function(){
// 'this' here means window element.
self.animate();
}, 1);
}
}
you cant not use this in setInterval
use this code
edite this.animate() to example.animate()
use this code
var example = function(){
this.animate = function(){
console.log("Animate.");
}
this.updateTimer = function(){ // This is being called...
this.timer = setInterval(function(){
example.animate(); // A "Undefined Is Not A Function" error is being thrown here.
}, 1);
}
}
Related
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 4 years ago.
I am trying to understand the bind method and I have written the below code :
//
//Window Context
function Hello(d) {
//Always this reffers to calling context
console.log(d);
}
Hello("ABC");
function Student(sname) {
this.name_n = sname;
this.hello = Hello;
this.printAfter2Seconds = printAfter2Seconds.bind(this);
this.print = function() {
console.log(`Student Name: ${this.name_n}`);
}
}
printAfter2Seconds = function() {
console.log(`Before Set TimeOut - ${this.name_n}`);
//let that = this;
setTimeout(function() {
//console.log(this);
console.log(`After Set TimeOut - ${this.name_n}`);
},2000);
}
function Department(dname) {
this.name_n = dname;
this.hello = Hello;
this.printAfter2Seconds = printAfter2Seconds.bind(this);
}
let s = new Student("ABC");
s.hello(s.name_n);
s.printAfter2Seconds();
let d = new Department("IT");
d.hello(d.name);
d.printAfter2Seconds();
//
If I comment the setTimeout line and the line ending setTimeout like below :
//setTimeout(function() {
//console.log(this);
console.log(`After Set TimeOut - ${this.name_n}`);
// },2000);
I am getting the expected output ABC and IT. But If I include setTimeout I am getting undefined both time. So I am guessing some where I need to invoke bind again. This may not be a trivial example that you use everyday just trying to understand bind.
So I need to understand how to bind the this context of the function inside setTimeout or that is even possible.
Thanks in Advance.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
'this' in function inside prototype function [duplicate]
(8 answers)
Closed 4 years ago.
How do I make my objects property available within the callback?
//entrypoint.js
var DeviceManager = require('./class')
DM = new DeviceManager()
DM.start();
var t = setInterval(function() {
console.log("Module.isLoaded = " + DM.isLoaded);
}, 500);
setTimeout(function() {
console.log("Stopping");
clearInterval(t);
DM.stop();
}, 10000);
//class.js
module.exports = class DeviceManager {
constructor(){
this.isLoaded = false;
this._timer= null;
}
start(){
console.log('starting timer')
this._timer = setInterval( function() {
console.log('timer callback')
this.isLoaded = !this.isLoaded;
},1000)
}
stop() {
console.log('stopping timer')
clearInterval(this._timer)
}
}
Basically this line doesnt work, because it doesnt have access to the correct this I assume.
this.isLoaded = !this.isLoaded
Also, since im all around pretty new at this, any feedback/corrections are very welcome.
Try using an arrow function for your setInterval while it's in the class.
An arrow function expression has a shorter syntax than a function expression and does not have its own this
start() {
this._timer = setInterval( () => {
this.isLoaded = !this.isLoaded;
}, 1000)
}
This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Closed 6 years ago.
Why is clearInterval() not working? what am I doing wrong? I tried a bunch of things but they don't seem to work out...
var s = 60;
var timer = null;
function Ftimer (){
document.getElementById("sec").innerHTML = s--;
}
document.getElementById("start").onclick = function () {
var timer = setInterval(function(){ Ftimer() }, 1000);
}
document.getElementById("stop").onclick = function () {
clearInterval(timer);
}
var timer makes the scope to the onclick function, not the global variable.
timer = setInterval(Ftimer, 1000);
This is due to you overwriting your initial timer variable here:
document.getElementById("start").onclick = function () {
// this clobbers your previous `timer` assignment
var timer = setInterval(function(){ Ftimer() }, 1000);
}
So fix it by simply removing the var and use the outer scoped timer variable:
document.getElementById("start").onclick = function () {
// this assigns to your previous `timer`
timer = setInterval(function(){ Ftimer() }, 1000);
}
I am having a hard time getting a countdown timer working as I don't know what I am doing wrong. I am trying to setup a countdown timer using jQuery in a prototype.
The main problem I see so far is at the setInterval:
_self.counter = setInterval(_self.runTimer(_self),1000);
When I don't pass in the "this" I get NaN but when I do the countdown only happens once and then stops.
Here is my JSFiddle work so far:
http://jsfiddle.net/f9GN7/
Thank you in advance.
I've modified a little of your code, I changed setInterval to setTimeout.
var timer_code = function(){
this.counter;
this.timeCountDown = 30;
}
timer_code.prototype = {
init : function(){
var _self = this;
$('#start').on('click',function(e){
_self.setTimer();
});
},
setTimer : function(){
var _self = this;
// _self.counter = setInterval(_self.runTimer(_self),1000);
var timerLoop = function(){
if(_self.timeCountDown > 0){
_self.runTimer();
setTimeout(timerLoop, 1000);
}
};
timerLoop();
},
runTimer : function(){
var _self = this;
_self.timeCountDown--;
if(_self.timeCountDown <= 0){
// clearInterval(_self.counter);
$('#timer').html("DONE");
return;
}
$('#timer').html(_self.timeCountDown);
console.log(_self.timeCountDown);
}
}
var timer = new timer_code();
timer.init();
http://jsfiddle.net/f9GN7/1/
setInterval gets a function reference as its first parameter ..
This function may not return a function object, the function call you just passed needs to be called in the scoope of a closure
Keeping your code with just a few modifications :
setTimer: function(){
if(this.counter)
clearInterval(this.counter); // timer may have already been launched, it may need to be cleared if its value is an integer and is != 0
this.counter = setInterval(
(function (ref) {
return function () {
ref.runTimer();
}
})(this),
1000);
}
See Fiddle Here
This question already has answers here:
JavaScript setInterval and `this` solution
(9 answers)
Closed 5 months ago.
I'm trying to get my head round this context problem while using prototypal inheritence (which I've not really played with before). I have an AutoScroller object:
function AutoScroller() {
this.timer = null;
}
AutoScroller.prototype = {
stop: function() {
if (this.timer == null) {
return;
}
clearInterval(this.timer);
this.timer = null;
console.log("stop");
},
start: function() {
if (this.timer != null) {
return;
}
this.timer = setInterval(function() { this.move(); }, 3000);
console.log("start");
},
move: function() {
console.log("move");
}
};
On document ready, I initiate everything by doing this:
var scr = new AutoScroller();
$('div.gallery p.stopBtn').bind("click", scr.stop);
$('div.gallery p.startBtn').bind("click", scr.start);
The problems all arise because "this" always refers to 'p.startBtn' and not scr, so when the start function with setInterval is called I'm getting an error "this.move() is not a function".
I know context is a fairly fundamental concept of which I appear to have no idea. Any ideas on how to sort this out?
Change start to this:
start: function() {
if (this.timer != null) {
return;
}
var that = this;
this.timer = setInterval(function() { that.move(); }, 3000);
console.log("start");
}
I finally worked it out... I used a closure in the button click like this:
var scr = new AutoScroller();
$('div.gallery p.startBtn').bind('click', function(x) {
return function() {
x.start();
}
}(scr));
And also implemented the change mentioned by SimpleCoder above.
You can also pass the current object instance in setInterval method, so that it always has the access to 'this'.
Verified on IE11, Chrome, Opera and Firefox.
setInterval(function (objRef) {
objRef.foo();
}, 500, ***this***);