This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
var preGameRequest = new XMLHttpRequest();
var preGameData;
preGameRequest.open("GET", "/matches/live.json");
preGameRequest.onload = function() {
preGameData = JSON.parse(preGameRequest.responseText);
}
preGameRequest.send();
console.log(preGameData); // main problem is here
Here is my code. I defined preGameData as global and tried to save /matches/live.json file's data into preGameData. And when I try to console.log(preGameData) from outside of the scope (like in the code section) I get 'undefined' as a return. And if I try to console.log(preGameData) from inside of the scope it works. I don't really know what's going on.
That code should work:
preGameRequest.onload = function() {
preGameData = JSON.parse(preGameRequest.responseText);
console.log(preGameData);
}
The reason: is that preGameRequest.send() function operates asynchronous.
When the browser tries to execute console.log() (in your example), the http response is not recieved yet, and the variable is really undefined.
But if you place console.log() inside of the handler (as in my example), it would be executed at moment, when the response is already recieved (straight in the onload() handler). And that's why the variable preGameData would be defined already.
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)
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I have the whole code wrapped by an async function, i'm using puppeteer basically.
If i use a simple fs.fileRead function, save the result of data inside a var then the code can read that variable in the next async function, and from my understanding it can read it exactly because is async same as the fs.fileRead function.
The problem comes when I try to do another fs.fileRead, way before the above, but in the same tree level, and try to read the variable saved inside it, in a if (){ statement right after, outside the fs.fileRead, I tried using a function but doesn't work either, below the example:
var fullcsv, filecsv;
fs.readFile('myfile.csv', (err, data) => {
if (err) {throw err;}
fullcsv = data.toString();
if(fullcsv.includes(urldom)){
filecsv = 0;
}else{
filecsv = 1;
}
processFile(filecsv);
});
var dog;
function processFile(filecsv) {
dog= filecsv;
}
console.log(dog);
if (urllink != "" && processFile() == 1){
...
The console says console.log(dog) is undefined , and the if statement turns out to be false cause it goes directlye to the else statement.
p.s. I also tried with fs.fileReadSync but does literally no difference at all.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
as mentioned above i have an issue getting the data out of the scope, which i set in the scope before in an asynchronous callback function.
Here is some of my Code:
var TransactionCtrl = require("controller/transactions.controller");
var onSuccess = function(_response) {
this.showData = _response;
};
var TransactionsFunction = function() {
//preparing asynchronous call
var transactionCtrlInstance = new TransactionCtrl(onSuccess.bind(this));
//firing asynchronous call
transactionCtrlInstance.getTransactions();
};
TransactionsFunction.prototype.run = function() {
//show this.showData
console.warn(this);
console.warn(this.showData);
};
module.exports = TransactionsFunction;
Important to mention is, that i call the "run" function definitely after the asynchronous call returned, so the data should be applied in the scope.
Does somebody have an explanation or a workaround for this?
Does the scope behave different in a callback function even if i bind the scope on it?
Calling the run method on new TransactionsFunction() will not guarantee that the async call had been completed.
The new TransactionsFunction() would fire the asysnc call and then exit.
If you call run() the async call may still have not been returned.
The only place you can ensure that the data has been returned is the onSuccess () method.
Your can check out incorporating such behavior using Promises.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I've clearly been writing too much CoffeeScript, as I am now realizing I do not have even a basic understanding of scope in pure JS.
After playing for a while, I cannot figure out the problem with the following--
$(document).ready(function() {
var myUrl = "http://notimportant.com/"
var photos = getPhotos(myUrl);
console.log(photos); //undefined
});
function getPhotos(url) {
var a;
$.get(url, function(data) {
a = data["photoset"]["photo"];
console.log(a); //my object
});
return a;
}
If I put a console.log(a) statement on the line right below 'var a = data["photoset"]["photo"];' it shows that it properly makes the GET request I'm looking for. But I'm finding it impossible to pass that object back to my main block of code, where I want to manipulate it.
Thanks in advance.
The reason photos is undefined is not because of scopes. Its because $.get is executed asynchronously. $.get() returns jqXHR object instead of an HTTP response.
onSuccess callback should be passed to getPhotos() in order to make it work correctly. Alternatively when().then() construct could be used.
$(document).ready(function() {
var myUrl = "http://example.com/";
getPhotos(myUrl, renderCatPhotos);
});
function getPhotos(url, onSuccess) {
$.get(url, onSuccess);
}
function renderCatPhotos(data) {
var a = data.photoset.photo;
console.log(a); // a is always available
}
note: you might not even need getPhotos function. You can simply $.get(url, onSuccess); in $(document).ready() instead.
Its not a matter of scope, its a matter of that you are returning an undefined variable before the $.get defines it. Consider making photos a global, then setting it in the $.get success function instead of setting it to 'a'. Inside the success function, you can then issue calls to other functions that would control displaying/processing the photos.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
function getData() {
var photo,
comment,
url;
$.getJSON('http://url.info/verify/settings.php', function (data) {
photo = data.photoMSG;
comment = data.commentMSG;
url = data.photoURL
});
console.log(photo); //undefined
console.log(comment); //undefined
console.log(url); //undefined
}
I'm getting undefined in console log for all of them... How to get these 3 vars visible outside of getJOSN block? I know this have been asked x100 times, I tried windiw.varName but still the same thing..
It's not a scope issue, it's an asynchronous issue. Everything inside the getJSON handler is asynchronous -- so the console.log calls will usually happen after the variables get assigned. Use an async callback instead:
$.getJSON('http://url.info/verify/settings.php', function (data) {
photo = data.photoMSG;
comment = data.commentMSG;
url = data.photoURL;
callback(photo, comment, url);
});
function(photo, comment, url) {
console.log(photo); //undefined
console.log(comment); //undefined
console.log(url); //undefined
}
Because $.getJSON is doing an ajax call, but the code after that is called before the callback within the getJSON is called. So the vars are still undefined. A typical "problem" with asynchronous behaviors.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I'm trying to get a variable (lib) out of a multiple nested functions.
var nme='name',lib;
$('script').each(function(){
var src=$(this).attr('src');
if(typeof(src)==='undefined'){src='';}
if(src.indexOf(nme)!==-1){
$.get($(this).attr('src').match(/\w([^ ]+)spbin/)[0]+'/conf/ptmedia.plist',
function(c){
$(c).find('key').each(function(){
if($(this).html()==='MediaLib'){lib=$(this).next().html();}
});
}
);
}
});
if(lib==='some lib'){DO STUFF}
Your problem isn't with scoping, the problem is that you have an AJAX call which is asynchronous.
You should put the change of HTML in .null inside the callback function instead:
$.get($(this).attr('src').match(/\w([^ ]+)spbin/)[0]+'/conf/ptmedia.plist',
function(c){
$(c).find('key').each(function(){
if($(this).html()==='MediaLib'){lib=$(this).next().html();}
$('.null').html(lib);
});
}
});
In JavaScript often IO is asynchronous. This means that when you make an AJAX call it does not happen immidiately but rather waits for the value to return from the HTTP request and then calls a callback. In your case that function(c) is the callback, it gets executed when the value of the AJAX call arrived.
So in fact you were updating the HTML content of .null to undefined, since it got the value of lib before it was updated.
I solved this problem as follows:
var nme='name';
$('script').each(function(){
var src=$(this).attr('src');
if(typeof(src)==='undefined'){src='';}
if(src.indexOf(nme)!==-1){media=$(this).attr('src').match(/\w([^ ]+)spbin/)[0];}
});
function ffn(){
$($.ajax({url:media+'/conf/ptmedia.plist',async:false}).responseText).find('key').each(function(){
if($(this).html()==='string'){value=$(this).next().html();}
});
return value;
}
if(ffn()==='some lib'){DO STUFF}
Thank you all for your participation and good ideas!