This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Javascript closure not working
(1 answer)
Closed 5 years ago.
I have a function with a callback that checks whether or not a file exists on my server, with the result returned being either "true" or "false". My problem is that i am calling this "DoesFIleExist" function in a for-loop with the "id" calculated earlier in the function. The problem is that whenever one of the function calls is resolved and tries to call "AddResultToPage" it uses the id of the last for-loop iteration, when it should be using the id it was given when the function was called.
The "DoesFileExist" function takes a path and a callback as parameters.
Any help would be much appreciated, as i have looked online and on here but most of the answers i have found are relating to buttons and event listeners on the buttons.
DoesFileExist('/XML/'+id.trim()+'.xml',function(data) {
console.log(id.trim()+" "+data);
if (data == "true") {
(function () {
console.log("adding to page - "+id.trim());
AddResultToPage(id,false);
})();
}else{
console.log("the file does not exist");
}
Put it in a self invoking function:-
(function(id){
DoesFileExist('/XML/'+id.trim()+'.xml',function(data) {
console.log(id.trim()+" "+data);
if (data == "true") {
(function () {
console.log("adding to page - "+id.trim());
AddResultToPage(id,false);
})();
}else{
console.log("the file does not exist");
}
})}(id)) // now, your inner code has reference to correct id due to closure
What happens is, by the time your response from server is received, the for loop had been completed and id gets set to last value.
With closure, id will refer to the value passed in the function and not the one in loop
You can use a specificId with let (that will stay in your scope, it is ES6). There is a related SO post about closures :
How do JavaScript closures work?
DoesFileExist('/XML/'+id.trim()+'.xml',function(data) {
let specificId = id;
console.log(id.trim()+" "+data);
if (data == "true") {
(function () {
console.log("adding to page - "+specificId.trim());
AddResultToPage(specificId,false);
})();
}else{
console.log("the file does not exist");
}
Related
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.
I'm not new to js but there's a stupid problem with jquery get method that it can't change global variable and I don't know why?
function getData(data) {
re=null;
$.get("http://example.com/api.php",{ d:data}).done(function(result){
re = true;
}).fail(function(){
re = false;
});
console.log(re);
return re;
}
If you see the console it's still null !
Any ideas?
UPDATE :
My problem is not with console.log() , actually the problem is that I cant store and return value like this :
alert(getData(data));
This still returns null.
This is because $.get is an asynchronous call and by the time re variable is reassigned a new value, console.log is getting executed.
You can use a callback function when calling your async function getData(data).
function getData(data,callback) {
$.get("http://example.com/api.php",{ d:data}).done(function(result){
callback(true)
}).fail(function(){
callback(false);
});
}
//call it with your data and callback function
getData(data, function(response){
console.log(response); // this will contain true or false as returned from your getData function.
})
I hope this helps.
This question already has answers here:
How do I return the accumulated results of multiple (parallel) asynchronous function calls in a loop?
(5 answers)
Closed 6 years ago.
I have this function
function add_cnh(arr_clelem){
var id=arr_clelem.getElementsByClassName("present")[0].id;
var date=arr_clelem.getElementsByClassName("present")[0].getAttribute('date');
var tt_entry= arr_clelem.getElementsByClassName("present")[0].getAttribute('tt_entry');
//new Ajax.Updater('register', '/some_url', { method: 'get' });
new Ajax.Request('/attendances/new',
{
parameters:'id='+id+'&date='+date+'&timetable_entry='+tt_entry+'&subject_id='+subject_id,
asynchronous:true,
evalScripts:true,
method:'get'
/*onSuccess: function(transport) {
var response = transport.responseText || "no response text";
alert("Success! \n\n" + response);
}*/
}
)
var ret=modal_data;
// $$('.MB_close').invoke('observe', 'click', _deinit);
return ret;
}
This function takes html-elements-object as an argument and basically render a modal-box and that modal box contain a form -elements which i need to store inside an array. The variable modal_data contains the elements which I require and its a global variable define in another file.
My problem is
This is a very old project using many JavaScript frameworks and libraries which date back to 2006 the library responsible for opening the model box itself is deprecated as can be seen here
And somehow I don't want to get into server side so I am using a for loop something like this
for(var i=0; i<arr_of_elements.length, i++)
{
my_arrvar[i]=add_cnh(arr_of_elements[i]);
}
Now with each itteration since I want the modal box to get closed and store the data within 'my_arrvar' which is somehow not possible as the call is asynchronous in nature and I've used closures and callbacks but no success. I don't want to use any sort of timer. So this is how it goes
Call the function and get data for each call and remove the modal box by id.
Also can this be used somehow and if then how?
You have to pass in ajax request asynchronous:false instead of true. Otherwise its not possible by another way.
Other Way using jQuery
The easiest way is to use the .ajaxStop() event handler:
$(document).ajaxStop(function() {
// place code to be executed on completion of last outstanding ajax call here
});
See jQuery Event handler
This question already has answers here:
How can I get an element's innerHTML to update immediately?
(2 answers)
Closed 7 years ago.
Title may not be perfectly clear, but I try to explain my problem using example.
I have function which may take quite some time to execute, so I want to notify user when this function is executing. I want to show notification when the function is starting and delete it when function ended.
This approach works exactly how I want:
function foo()
{
var r = document.getElementById('id');
r.innerHTML = 'processing...';
reallyLongFoo();
r.innerHTML = 'done!';
}
But I prefer to change notification by another function. Like that:
function foo()
{
changeInfo('processing...');
reallyLongFoo();
changeInfo('done!');
}
function changeInfo(info)
{
var r = document.getElementById('id');
r.innerHTML = info;
}
However this version isn't working correctly. Value 'result' isn't changing until function ends and it goes directly to 'done!', skipping 'processing...'
I'm guessing that both changInfo Functions are executed after foo. How to force them to be executed immediately?
Try something like below by adding a callback.
function foo()
{
changeInfo('processing...');
reallyLongFoo(function() {
changeInfo('done!');
});
}
function changeInfo(info)
{
var r = document.getElementById('id');
r.innerHTML = info;
}
function reallyLongFoo(callback)
{
//Put all your codes
callback();
}
mate, you can use jquery promise or something similar to achieve this, but it's not that nice, they are not natively implemented, the best thing you can do is make the second changeInfo as a call back on your long foo, just call it after you done the dom manipulation.
when you putting two method call in one method, no matter how long it takes, they execute and returns, but inside one method, all the single line of code executes in sync mode.
function foo()
{
changeInfo('processing...');
reallyLongFoo(function() {
changeInfo('done!');
});
}
function changeInfo(info)
{
var r = document.getElementById('id');
r.innerHTML = info;
}
function reallyLongFoo(callback)
{
//Put all your codes
callback();
}
Just reference Deepak's code, but same idea!
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I try do this :
<script>
FB.getLoginStatus(function(response) {
if (response.status==='connected') {
var fb_status="on";
} else {
var fb_status="off";
}
});
alert("ok"+fb_status);
</script>
If i put alert inside function , this alert works , by other side , if i put this alert outside , no works
i supose this it´s more or less the same as global vars in php but no have many experience in Javascript
I only need the same i put in the example for detect in a var the result from function but as in the case i put as example , outside function , i try many things but no get results
Regards and thank´s for the help to community
FB.getLoginStatus is async function so when you try getting fb_status outside it, you get undefined because FB.getLoginStatus didn't return any result yet
As the FB.getLoginStatus call is asynchronous, the result only occurs later and is only relevant inside the event handler:
e.g.
<script>
FB.getLoginStatus(function(response)
{
// This line gets called many millisconds later
console.log("When I have a status");
if (response.status==='connected')
{
var fb_status="on";
}
else
{
var fb_status="off";
}
alert("ok"+fb_status);
});
// This line executes long before the callback returns
console.log("After call");
</script>
Check out the console to see the order of events:
"After call"
"When I have a status"
You mention in comments you want to use the value elsewhere. The problem will be the timing as the result you want will only occur later.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
JavaScript asynchronous return value / assignment with jQuery
I have the following javascript code, the time.php file has minute and hour output using json_encode function. If I move console.log inside the getJSON function it finds the correct values, however when I move it outside the function it shows as undefined.
var my_hour;
$.getJSON('../scripts/time.php', function(data) {
my_hour = data.hour;
});
console.log(my_hour);
The "$.getJSON" call is asynchronous; the interaction with the server takes time but the browser does not wait for it to finish. Thus, your code after the function call runs immediately, a long time before the callback runs.
it's because it's asynchronous. Ajax request made by $.getJson async call your script and variables my_hour is initialized after your console.log(my_hour).
If you want it to work that way, then you should put console.log in some setInterval.
http://www.w3schools.com/jsref/met_win_setinterval.asp
var interval = setInterval(function(){
if (my_hour != undefined){
console.log(my_hour);
clearInterval(interval);
}
}, 200);
But it's it's not a good practice anyway.., your code should be placed in callback function as mentioned above.
var my_hour;
$.getJSON('../scripts/time.php', function(data) {
my_hour = data.hour;
console.log(my_hour);
});