Javascript: settimeout problem - javascript

When I start my script I have this:
var my_great_masterpiece = new function ()
{
var self = this;
Then later in my script I have this:
response_xml: function ()
{
if (self.http_request.readyState == 4)
{
if (self.http_request.status == 404 && countXmlUrl <= 3)
{
countXmlUrl++;
self.realXmlUrl = xmlUrl[countXmlUrl];
self.request_xml();
}
if (self.http_request.status == 200)
{
self.xmlDoc = self.http_request.responseXML;
self.storage.setItem('domains_raw_xml', self.http_request.responseText);
self.main.peter_save_data();
self.timervar = setTimeout(function ()
{
// ########### Below line gives the error #############################
self.new_version_show_window();
}, 2000);
}
}
},
new_version_show_window: function ()
{
...
}
the error that I am getting is:
Error: self.new_version_show_window is
not a function
What am I doing wrong?
Thanks!

It is unclear from your code where new_version_show_window is defined. Maybe you could explicitly define it on self:
self.new_version_show_window = function () {
/* ... */
}
instead. Or you could define it in the local namespace and use it directly in the setTimeout call:
self.timervar = setTimeout(function () {
new_version_show_window();
}, 2000);
or simply:
self.timervar = setTimeout(new_version_show_window, 2000);
Because of closure, the variables declared in the outer function is also available in the inner function.
Edit
Thanks for posting the entire code. new_version_show_window is defined on this.main, so you must access it thusly:
self.timervar = setTimeout(function () {
self.main.new_version_show_window();
}, 2000);

It could be that self is a reserved word in JavaScript [1]. This could be causing you some problems so try naming the variable something different to start with.
[1] http://www.quackit.com/javascript/javascript_reserved_words.cfm

This is a problem of scope. new_version_show_window is only in scope in the construct in which is it called ( apparently a jQuery AJAX function of some sort). It will only be available to my_great_masterpiece if you define it outside the limited scope in which it now exists.

Related

How to ClearTimeout of a function in JavaScript?

I have a function that will continuously reset every time a button is clicked, however, I am trying to clear that timer when a certain picture is on the screen. There are more things going on in the program but this is the general problem I am having. Here is what I have so far:
JavaScript:
function reset() {
var f = document.getElementById("ff").onclick;
var ft = setTimeout(function(){ dontf() }, 3000);
f = ft;
}
function dontf() {
document.getElementById("r").src="H.jpg";
}
function s() {
if (document.getElementById("r").src == "file:///C:/Users/S.jpg") {
clearTimeout(ft);
}
}
HTML
<button onclick="reset(); s();" id="ff">Fd</button>
You can look at this mate
All you needed to do is define var ft in a scope which is accessible by both of the dontf and s funtion
let timer;
function reset() {
const element = document.getElementById("resetButton");
timer = setTimeout(function(){ addImageFunc() }, 3000);
}
function addImageFunc() {
console.log(timer); document.getElementById("addImage").src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350";
}
function stopReset() {
if (document.getElementById("addImage").src == "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350") {
clearTimeout(timer);
}
}
<html>
<body>
<button onclick="reset(); stopReset();" id="resetButton">Fd</button>
<img id='addImage'>
</body>
</html>
Suggestions
Use proper naming convention for the variables and functions which will make your code more readable and easy debugging.
Don't use var. use let or const.
Try avoid using global scope variables unless there is no alternate way.
The scope of ft is unreachable since it is defined inside of a function. Need to move it to a scope where the other method is able to reference it.
var ft; // define it outside
function reset() {
// var f = document.getElementById("ff").onclick; <<-- no clue what this is doing
if (ft) window.clearTimeout(ft); // if it is running, remove it
ft = setTimeout(dontf, 3000);
// f = ft; <-- does not make sense
}
function dontf() {
document.getElementById("r").src="H.jpg";
}
function s() {
if (document.getElementById("r").src == "file:///C:/Users/S.jpg") {
if (ft) clearTimeout(ft);
}
}

How to clear setTimeout inside Javascript Object?

I have an object that I have a few functions inside that I am using setTimout inside. I'm trying to clear the timeout using clearTimeout.. but I'm not hitting it right.
var ExpireSession = {
killSession: function () {
var TESTVAR2 = setTimeout(function () {
window.location.href = "error/expired.aspx";
}, 15000);
},
stopTimers: function (){
clearTimeout(ExpireSession.killSession.TESTVAR2)
}
}
Before 15 seconds I am triggering: ExpireSession.stopTimers(); but it does not stop it. Any ideaas what I am doing wrong here?
var TESTVAR2 is a variable that is local to the function it is declared within. It is not a property of an object.
If you want to access it as a property of an object, then you must define it as such:
ExpireSession.killSession.TESTVAR2 = setTimeout(function () {
(You might be able to make use of this depending on how you call the function).
Because JavaScript has functional scope, TESTVAR2 will only be defined within killSession. To reference it, you can set it as a property of ExpireSession:
killSession: function () {
this._TESTVAR2 = setTimeout(function () {
window.location.href = "error/expired.aspx";
}, 15000);
},
stopTimers: function () {
clearTimout(this._TESTVAR2);
}

Javascript scope, how do I preserve the module

I have a function which calls itself recursively on a setTimeout. Problem is it loses its scope along the way.
So this is what I have...
var module = function () {
function init() {
if (notYetReadySoTryAgain) {
setTimeout(this.init,100);
return
}
}
}
The second time through I get an error that init cannot be found (on Window object).
What is the canonical way to deal with maintaining a reference to a module across a setTimeout?
Enclose the scope using self-execution; remove this as well.
var module = function () {
(function init() {
if (notYetReadySoTryAgain) {
setTimeout(init,100);
return
}
})(notYetReadySoTryAgain);
}
Remove this. and it will work.
var module = function () {
function init() {
if (notYetReadySoTryAgain) {
setTimeout(init,100);
return
}
}
}
Using setInterval can also be option for you.
try this:
var module = (function () {
(function init() {
if (notYetReadySoTryAgain) {
setTimeout(init,100);
return
}
})()
})()

Passing local functions to setTimeout()

I have written the following function.
function obj()
{
this.a;
}
obj.prototype.catch = function()
{
alert('Catched')
}
obj.prototype.do = function()
{
alert('called');
}
What i need is, to call obj::catch() after obj::do() is called and the call must be performed from inside obj::do()
So how to pass the local function of obj to setTimeout
i have tried
obj.prototype.do = function()
{
window.setTimeout('"'+this.catch+'()"',1000);
alert('called');
}
It does not worked
Then i tried
obj.prototype.do = function()
{
window.setTimeout('"'+this+'.catch()"',1000);
alert('called');
}
which gave me the following error on Chrome console
Uncaught SyntaxError: Unexpected token ILLEGAL
So i tried the following dirty method(is it really dirty ?)
obj.prototype.do = function()
{
this.pid = randomVal(100);
window['temp'+this.pid] = this;
window.setTimeout("temp"+this.pid+".catch();",1000);
alert('called');
}
function randomVal(bound)//returns a random number between 0 and <bound>
{
return (Math.floor(Math.random()*(bound)));
}
That worked.
so why the first two methods not worked.Is there any other way to do the same thing without global variables..
The second method and last method are almost similar .But why am i gettng the error in second method..?
The worked code can be found here
http://jsfiddle.net/jXhAs/
Don't pass strings to setTimeout … ever.
var self = this; // Because the scope will change
setTimeout(function () { self.catch() },1000);
Or if you are using JS 1.8.5:
setTimeout(this.catch.bind(this),1000);
You can read more about bind
You should pass a function to setTimeout (not a string):
Example:
var self = this;
setTimeout(function(){
self.catch();
},1000);
use a closure
obj.prototype.do = function()
{
window.setTimeout((function(that){
return function(){
that.catch();
};
})(this),1000);
alert('called');
}
Why go through all of this effort, just pass the function.
function obj() {
this.a;
}
obj.prototype.
catch = function() {
alert('Catched')
}
obj.prototype.do = function() {
setTimeout(this.
catch, 1000);
}
var test = new obj();
test.do();​

How do you add objects to a javascript namespace?

var Test = (function() {
return {
useSub: function () {
this.Sub.sayHi();
},
init: function () {
$(document).ready(this.useSub);
}
};
})();
Test.Sub = (function () {
return {
sayHi: function () {
alert('hi');
}
};
})();
Test.useSub(); // works
Test.init(); // explodes
Above I am trying to create a Test namespace and add an object Sub to it. I was doing fine until I tried using the object in jQuery. The error is "Uncaught TypeError: Cannot call method 'sayHi' of undefined". If there is a better way to do this, I am open to it.
Edit:
Obviously this was demo code. In my real application the solution that I went with because I think it is the most clear is this one:
var Namespace (function () {
return {
init: function () {
$(document).ready(function() {
Namespace.onReady();
}
},
onReady: function() {
alert('Now I am back in the Namespace scope. Proceed as planned');
}
};
})();
Edit2: All jQuery callbacks seem to require they are used in this manner or else the scoping is screwed up.
I think it is a scope problem. If you do
$(document).ready(this.useSub);
then this.useSub will be executed in the window scope (so inside the function, this refers to the window object) and there doesn't exist a Sub attribute.
Try:
init: function () {
var obj = this;
$(function(){obj.useSub()});
}
For some reason it does not work using $(document).ready(function(){obj.useSub()}); but it works with the $() shortcut.
Here is one way
var Test = {
useSub : function () {
Test.Sub.sayHi();
},
init: function () {
$(document).ready(Test.useSub);
},
Sub: {
sayHi: function () {
alert('hi');
}
}
};
in this line:
$(document).ready(this.useSub);
you're passing a reference to a function and the scope is lost- when the function runs, this no longer means Test.

Categories