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 1 year ago.
I have a global variable called result and a function, with the purpose of changing the value of result. here's the code I've tried:
checkdate();
function checkdate() {
//defining startdate,enddate,hotel_id
$.ajax({
method: 'GET',
url: '/checkdate',
data: {startdate : startdate, enddate : enddate, checkroom : 1, hotel_id : hotel_id},
success: function(response){
storeResponse(response);
}
});
}
var result = [];
function storeResponse(response) {
window.result = response;
}
alert(result);
The alert returns nothing, however if I put the alert INSIDE the function, it returns response alright. This seems to be easy but I can't figure it out.
The function is invoked before all this code.
There are two things you need to know here:
var result is not same as window.result so use window.result = "Test"; and not the var declaration.
You need to invoke storeResponse() before alert code so that it set the new value and then get that value in alert.
window.result = "Test"; //in global scope
function storeResponse(response) {
window.result = response;
console.log(window);
}
storeResponse("Hello");
alert(result);
You should call the function first so that the result variable is populated.
var result = []; //in global scope
function storeResponse(response) {
window.result = response;
}
storeResponse('callSomething');
alert(result);
You said you are invoking the function first, so you must have something like this:
storeResponse('someResponse');
var result = []; //in global scope
function storeResponse(response) {
window.result = response;
}
alert(result);
The issue is the following:
In first line you are calling your function. The function sets a new result var in the window, global scope
In the second line, you are overwriting the result var: var result = []; It lets you with an empty array, that's why the alert looks empty
Try commenting the second line and it will work:
storeResponse('someResponse');
//var result = []; //in global scope
function storeResponse(response) {
window.result = response;
}
alert(result);
Or even better, declare the var first:
var result = [];
storeResponse('someResponse');
function storeResponse(response) {
result = response; // You don't need to use window (if the var is not declared inside the function, is global by default)
}
alert(result);
Thats because AJAX is asynchronous. Meaning the code is non-blocking.
Imagine the AJAX call being passed to another thread for processing while the rest of the code is executed. The alert is triggered before the AJAX request has received it's response. Thats why if you do the alert inside the callback it works.
Related
I'm having an issue with the javascript scope / order of execution. I create an empty object inside a function. Then I add some properties in a child function. The properties haven't changed in the parent function, though.
$scope.finder = function (obj) {
var id = obj.oid;
var crit = MC.Criteria('_ownerUserOid == ?', [id]);
theResult = {}; // Scope should be finder function.
database.findOne(crit) // This is a Monaca method for finding from database
.done(function(result) {
// Returns and empty object as expected.
console.log(JSON.stringify(theResult));
theResult = result;
// Returns the search result object as again expected.
console.log(JSON.stringify(theResult));
});
// Here's the issue - when I log and return theResult, I get an empty object again.
// I think it has to do something with the scope.
// Also, this logs to console before either of the console.logs in the done function.
console.log(JSON.stringify(theResult));
return theResult;
};
I think you forgot the "var" before declaring the variable
var theResult = {}
It looks like you are performing an asynchronous request for some data. Any time you are performing asynchronous JavaScript, you will need to keep in mind that things aren't called sequentially. When an asynchronous call is made, JavaScript will carry on executing code down the stack.
In your case, theResult will be an empty object because database.findOne(crit) has not finished executing by the time you call console.log(JSON.stringify(theResult));
Because of this, you cannot return from $scope.finder, instead you could pass a callback into $scope.finder and execute that once database.findOne(crit) has finished executing.
$scope.finder = function (obj, callback) {
var id = obj.oid;
var crit = MC.Criteria('_ownerUserOid == ?', [id]);
theResult = {}; // Scope should be finder function.
database.findOne(crit) // This is a Monaca method for finding from database
.done(function(result) {
// Returns and empty object as expected.
console.log(JSON.stringify(theResult));
theResult = result;
callback(theResult);
// Returns the search result object as again expected.
console.log(JSON.stringify(theResult));
});
};
Then call it like this.
$scope.finder({some: 'data'}, function(response) {
// response now has the values of theResult
console.log(response)
});
Change it to this:
$scope.finder = function (obj) {
return database.findOne(MC.Criteria('_ownerUserOid == ?', [obj.oid]));
};
// Client code:
finder({ oid: 'foo' })
.then(function(result) { console.log(JSON.stringify(result)); });
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 7 years ago.
var test = null;
$.get("/zeWebsite.php?blarg=421", function(data){
test = data.trim();
});
alert(test);
I always thought declaring the variable from outside the function before hand gave access to the variable even if called within the function. However, my test variable is still alerting as null.
It is likely an order issue as the $.get function is asynchronous. The callback of the get is not being run until after the alert has already fired.
The alert is being run BEFORE the get has completed. You need to make sure the get is complete before alerting by triggering alert within the callback.
Try:
var test = null;
$.get("/zeWebsite.php?blarg=421", function(data){
test = data.trim();
alert(test);
});
or
var test = null;
$.get("/zeWebsite.php?blarg=421", function(data){
test = data.trim();
outside();
});
function outside() { alert(test); }
it just not assigned yet..
You can simple wait for it:
var test = null, inprocess = true;
$.get("/zeWebsite.php?blarg=421", function(data){
test = data.trim();
inprocess = false;
});
var wait = setInterval(function(){
if (!inprocess) {
clearInterval(wait);
alert(test);
}
}, 500);
But this code is awful. Much better to trigger callback directly:
var test = null;
$.get("/zeWebsite.php?blarg=421", function(data){
test = data.trim();
anyactionwithtest(test);
alert(test);
});
Or use something like jquery deffered promise:
var test = null;
$.get("/zeWebsite.php?blarg=421", function(data){
test = data.trim();
}).done(function (data){
// data also accessible here as is
alert(test);
});
This is because you are using the variable before the get statement execute completely.
Test will get the value when the get function callback call.
If you place alert in get function then it will call at last.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I have a function that returns JSON information. I want to be able to store that into a variable and then use alert and the variable name to display the content returned from that function. Here is my code:
var getStuff2 (function (num) {
$.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent('http://catholic.com/api-radio/' + num) + '&callback=?', function(data) {
//console.log(data.contents);
//$('#response').text(data.contents);
obj = data.contents;
//alert(obj);
}];
return data.contents;
});
});
function getData(){
getStuff2(6387);
}
getData();
alert(getStuff2);
You have to put the alert inside of the callback handler for the AJAX function. AJAX calls are asynchronous which means that if you do something like this, the return won't work in the order you expect:
function getData() {
doAjax(function(data) {
obj = data.contents;
});
alert(obj);
}
You see, the AJAX call will return when it returns, and all of the code after it will just keep executing while the AJAX call is still waiting on a response.
So what you have to do is this:
function getData() {
doAjax(function(data) {
obj = data.content;
alert(obj);
});
}
I assume, that data.contents is a object, so your alert output will look something like [object object], so you just can't alert the content.
To make it globally available just store the content in a gloabl variable.
var result;
var getStuff2 (function(num) {
$.getJson(url, function(data)
result = data.contents;
});
}),
asynchronous functions cannot return values. Instead you need to explicitly do something with the value from inside the AJAX callback.
function getStuff(num, onContents){
$.getJSON(..., function(data){
//call the oncontents callback instead of returning
onContents(data.contents);
});
}
//when calling getstuff, pass a function that tells what to do with the contents
getStuff(6387, function(contents){
console.log(contents);
});
I have one simple question, been searching on Stack Overflow there are some questions on this topic but can't get a working solution.
I have a simple function for getting number of page likes on Javascript SDK:
function getLikes(div, graf) {
var numblike;
FB.api(graf, function(response) {
var numblike = response.likes;
$(div).prepend(numblike);
});
return numblike; // can't get it to return
}
var pLike = getLikes ("#mydiv", /app_id); // always undefined
Function works and it pre-pends the right number to my div but return always sets my variable to undefined. I understand that the script runs asynchronous and I need to use a callback function but I just can't get it right.
This is called javascript event loop. you can't return numblike from the function cause it's set only in the callback of FB.api.
So you can do similar to that - just send callback:
function getLikes(div, graf,callback) {
FB.api(graf, function(response) {
var numblike = response.likes;
$(div).prepend(numblike);
callback(numblike);
});
}
getLikes ("#mydiv", /app_id,function(numblike){
alert(numblike);
}); // always undefined
You have decalred numblike two times, just remove var declaration in the second one:
function getLikes(div, graf) {
var numblike;
FB.api(graf, function(response) {
numblike = response.likes; // var removed
$(div).prepend(numblike);
});
return numblike;
}
For example
function getResult(field) {
$.ajaxSetup ({cache: false, async: false});
$.get("api.php?field="+field, function(i) {
result = i;
});
return result;
};
The problem with this is that result becomes global. If I do var result = i; then the parent function (getResult) cannot see the variable result.
Is there a clever way to do this?
The code that I have posted works correctly. I have set my AJAX calls to be done synchronously.
function doIt(arr) {
var result = [];
$.each(arr, function (y_u_key_jQuery_y_u_no_fix_api, value) {
result.push(value);
});
return result;
}
Generally what you want to do is create a local variable in the outer function that the inner function manipulates through closure scope
Let's assume that your AJAX call is synchronous. You can try this:
function getResult(field) {
var result;
$.get("api.php?field="+field, function(i) {
result = i;
});
return result;
};
This way, the variable result is no more global.
$.get() is an asynchronous call. Trying to return something from it will not work like you think it will. If you want to do something with the result, you should do it in the success callback.
Here is the documentation on get.
You can't actually return a value from a asynchronous call, rather you have to depend upon the response will be be handled by a callback function to be called on response arrival.
function getResult(field, callback) {
$.get("api.php?field=" + field, callback);
};
USAGE
getResult("someFieldName", function(data) {
var result = data;
// do something with the response from server
});