Arun Karnawat Arun Karnawat - 3 months ago 17
Javascript Question

Why setInterval not stoped by clearInterval

var progressbar = {
progress : null,
html : function() {
var loadingHtml = '<div id="loader-wrapper" class="catalog-loadmore">';
loadingHtml += '<div class="progress"><div id="catalog-bar" class="progress-bar progress-bar-striped active" style="width: 10%"></div></div>';
loadingHtml += '<div class=""><span id="progress-valuenow"></span>%</div>';
loadingHtml += '</div>';
return loadingHtml
},
start : function() {
var width = 10;
this.progress = setInterval(function() {
$('#catalog-bar').css('width', width + '%');
$('#progress-valuenow').text(width);
if(width < 98){
width += 1;
}else{
this.stop(); // this is not working
clearInterval(this.progress); // this is also not working
console.log('else')
}
}, 100);
},
stop : function() {
clearInterval(this.progress);
},
destroy : function() {
clearInterval(this.progress);
$('#loader-wrapper').remove();

}
}


In the above code, why the following statement not working the else condition is executed
console.log('else')
is printing but clearInterval() not working. I am calling progressbar.destroy() from outside and it is working.

this.stop(); // this is not working
clearInterval(this.progress); // this is also not working


Can any one tell me what i that i am doing wrong.

Answer

You've passed anonymous function into setInterval, anonymous functions has context this setted to window, so you are targeting window.progress.

You have two ways to solve your problem:

  • store this in some variable like var _this = this; setInterval(function() { ... clearInterval(_this.progress) } ...)

  • use Function.prototype.bind() to set context of your anonymous function like setInterval(function() { ... clearInterval(this.progress) }.bind(this) ...)


Or set up transpiler for ES6 and use Arrow function which binds this automatically

Comments