JavaScript recursive setTimeout [duplicate] - javascript

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I defined this class in JavaScript:
function Signal(lbl, ho, tag) {
this.lbl = lbl;
this.ho = ho;
this.tag = tag;
this.getstatus = function () {
if (this.ho) {
$.get('/get.cgi?' + this.tag + '=?0', function (data) {
console.log(data);
setTimeout(this.getstatus, 1000);
});
}
};
}
Once getstatus is called, it should start calling itself with setTimout, but it doesn't! It only works one time.
If I use a function without a class, it works!
Please help me out.
Thanks!

The problem is when getStatus is invoked by the timer, this inside the method does not refer to the object, you can pass a custom value for this using bind(). Also note that in the ajax callback this refers to the ajax settings object.
function Signal(lbl, ho, tag) {
this.lbl = lbl;
this.ho = ho;
this.tag = tag;
this.getstatus = function () {
if (this.ho) {
var signal = this;
$.get('/get.cgi?' + this.tag + '=?0', function (data) {
console.log(data);
setTimeout(signal.getstatus.bind(signal), 1000);
});
}
};
}

Related

not able to update the UI from setTimeout() in vuejs [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 1 year ago.
i want to update name of person after every second in ui after feching name from lifeSpanObj object in .vue file (vuejs).
<div> {{personName}}</div> // in template using this this(its example not exactly this)
this.lifeSpanObj.forEach((element, i) => {
setTimeout(function () {
this.personName = element.name;
console.log(this.personName);
}, 1000);
});
using the above example i am able to print updated values in console but UI does not get updated. what could fix for this?
Make sure always use arrow function to not shadow this keyword:
this.lifeSpanObj.forEach((element, i) => {
setTimeout(() => { // arrow function instead of anonymous function
this.personName = element.name; // now this refers to the vue component
console.log(this.personName);
}, 1000);
});
for primitive function (in ES5) you can still follow the below approach
this.lifeSpanObj.forEach((element, i) => {
var self = this;
setTimeout(function () {
self.personName = element.name;
console.log(self.personName);
}, 1000);
});

How to run database queries synchronously in javascript [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 4 years ago.
let positionSettings = require('setting');
function getSetting(element) {
let setting;
positionSettings.find({element: element}, function (err,docs) {
console.log(docs[0].current); // output the value
setting = docs[0].current;
});
return setting;
}
$(document).on("click", "#save" , function(e) {
console.log(getSetting("abc")); // Output undefined
});
Why is the getSetting() function returning undefined. How can I achieve it.
Because it's an async function, you can't mix async and sync functions this way, try something like this:
let positionSettings = require('setting');
function getSetting(element, callback) {
positionSettings.find({element: element}, (err,docs) => {
let setting;
console.log(docs[0].current); // output the value
setting = docs[0].current;
callback(setting);
});
}
$(document).on("click", "#save" , (e) => {
getSetting("abc", (setting) => {
console.log(setting);
});
});
The fact is that you can't be sure that the data will be avaible after the function call, the only place that you have this sure is inside the callback.
And just a hint, use arrow functions to declare anonymous functions.

Can't call this inside arrow function [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I have problem when i'm trying to access by this keyword. I need to access run function inside updateTime
export class PlayerService {
createPlayer(): void {
return new window['YT'].Player(this.youtube.playerId, {
height: this.youtube.playerHeight,
width: this.youtube.playerWidth,
events: {
'onStateChange': (event) => {
function updateTime() {
//////I need to access | run function | from here
};
this.timeupdater = setInterval(updateTime, 100);
}
}
});
}
run (){
//some codes
}
}
I'm working on ionic 2
You need to go arrow function all the way
function updateTime() {
should be
var updateTime = () => {
or
setInterval(updateTime, 100);
should be
setInterval(() => updateTime(), 100);

JavaScript/JQuery: Correct passing of local variables from a loop to anonymous ajax callback function? [duplicate]

This question already has answers here:
Javascript infamous Loop issue? [duplicate]
(5 answers)
Closed 8 years ago.
Hello there I have the following problem - within a loop I have a certain number of jQuery ajax calls - in the return of the ajax call I want to use a local variable as well as the data returned by the ajax call:
In the JavaScript class DOCache.class.js (note that I use the global variable doCache here, which also does not "feel clean" but I do not know how to pass "this"):
function DOCache() {
this.cache = new Array();
this.capi = new JsonAPI();
// loads all the properties saved in the cache object
this.loadUpdateCache = function(allLoaded) {
for(var prop in this.cache) {
// a delay will be here for each object!
this.capi.get(this.cache[prop]['url'],(function(data) {
doCache.cache[prop]['data'] = data;
doCache.cache[prop]['ready'] = true;
if(doCache.cache[prop]['loaded'] instanceof Function) {
var propLoaded = doCache.cache[prop]['loaded'];
propLoaded(data);
}
// check all initialized
if(doCache.checkAllReady()===true && allLoaded instanceof Function) {
allLoaded(doCache.cache);
}
}) (prop) // KEY: If we have this, we get the correct prop - if removed, we get the correct data - but never both
);
}
};
}
In JsonAPI.class.js:
function JsonAPI(){
this.ajax = function(request_method,api_url,data,done,fail,always) {
var jqxhr = $.ajax(
{
type:request_method,
dataType: "json",
url: JSON_BASE+api_url,
data: data
},JSON_BASE+api_url,data)
.done(function(data) {
if(done instanceof Function) {
done(data);
}
})
.fail(function(data) {
if(fail instanceof Function) {
fail(data);
}
})
.always(function(data) {
if(always instanceof Function) {
always(data);
}
});
return jqxhr;
};
this.get = function(api_url,done,fail,always) {
return this.ajax('GET',api_url,"",done,fail,always);
};
}
The problem is that I do not know how to pass the local variable from the loop (which is a different string on each loop iteration) to the actual callback function without passing it explicitly using (prop) . But if I do this I do not get the data from the callback passed in.
So the actual question is: How can I use a local variable from an iteration (which obviously end before any ajax response is returned) in an Ajax callback function?
Try to aggregate your Ajax calls within an array. Then use $.when to set the callback:
var ajaxRequests = [];
var req1 = $.ajax();
ajaxRequests.push(req1);
$.when(ajaxRequests).done(function () {});
Note, this code is untested.

Undefined return in $.get jquery [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How to return AJAX response Text? [duplicate]
(2 answers)
Closed 9 years ago.
This question is already answered and voted. My edits are related to making it clearer and share some new knowledge acquired for other developers, I'm not expecting new answers.
I'm reading an XML with jQuery, but when I try to show an alert it's fully working; however, when I try to return the value it always gives me a message that it's undefined.
function getText(value){
var val;
var lang;
var location;
lang=getLanguage();
if (lang=='en')
lang='';
else
lang+='.';
location="resources/AppResources."+lang+'xml';
$.get(location, function (xml) {
$(xml).find("data").each(function () {
var name=$(this).attr('name');
if (name===value)
return $(this).find('value').text();
});
});
}
This is the code that calls it:
$(document).ready(function() {
alert(getText('AppTitle'));
});
If I add an alert in the return statement it shows me the value selected.
Small update:
As Arun P Johny explained in his answer, the missed part in my code was the callback that are defined by Mozilla in this way:
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.
You can't return a value from a async method, the easiest solution is to use a callback function like this one:
function getText(value, callback) {
var val;
var lang;
var location;
lang = getLanguage();
if (lang == 'en')
lang = '';
else
lang += '.';
location = "resources/AppResources." + lang + 'xml';
$.get(location, function (xml) {
$(xml).find('data[name="' + value + '"]').each(function () {
callback($(this).find('value').text());
});
});
}
$(document).ready(function() {
getText('AppTitle', function(value){
alert(value);
})
});

Categories

Resources