This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
Context
I have a function that is called within an AJAX call that returns a number. I set this number to a variable and want to access the number outside of the .done() method:
$.ajax({
url: 'urlhere.php',
type: 'GET',
data: {text: text},
success: function(data) {
var getNumber = countNumber();
getNumber.done(function(data) {
var number = data;
});
let newContent =
"The number is "+
number;
}
});
But I get this error, stating that the variable is not defined:
Uncaught ReferenceError: number is not defined
Question
How do I access variables within the .done() method in jQuery in an AJAX call?
Things I Have Tried
I have already tried defining the variable before the function call and then changing it in the done() method, like so:
var number; //initialize variable
$.ajax({
url: 'urlhere.php',
type: 'GET',
data: {text: text},
success: function(data) {
var getNumber = countNumber();
getNumber.done(function(data) {
number = data;
});
let newContent =
"The number is "+
number; //console.log's "undefined"
}
});
This only makes the variable equal to undefined, so I don't think anything inside the done() method is able to change existing variables. Any ideas? Let me know if there is any confusion. Thanks.
It seems getNumber.done() is asyncronous. Which means it takes a while to update the the value of number;
You may do this:
$.ajax({
url: 'urlhere.php',
type: 'GET',
data: {text: text},
success: function(data) {
var getNumber = countNumber();
getNumber.done(function(data) {
number = data;
let newContent = "The number is "+ number; //console.log's "undefined"
});
}
});
Your problem is that the code is asynchronous so the number variable won't be assigned just after you can the done() function.
var getNumber = countNumber();
getNumber.done(function(data) {
number = data;
});
// number won't exist here.
let newContent = "The number is "+ number; //console.log's "undefined"
What you can do:
Use a promise and use resolve on the done() callback. You will need to await after it.
Call a function from .done() callback and keep your process from there
Something like this:
var getNumber = countNumber();
getNumber.done(function(data) {
number = data;
// Your code should flow from here.
yourDoneFunction();
});
Related
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 2 years ago.
I have two functions main function which JQuery , and the other one in Javascript.
jQuery :
$(document).ready(function () {
$('#ProvisionLink').click(function () {
var queryTargetList = [ "Item1","Item2","Item3","Item4"]
var data = ["Data1","Data2","Data3","Data4" ]
event.preventDefault();
var i;
for(i = 0; i < queryTargetList.length; ++i) {
var dataItem = data[i];
var QueryItems = queryTargetList[i];
console.log("Before Launching the Javascript : " +QueryItems)
$.ajax({
url: '/operation',
data: {DataType: dataItem,},
type: 'POST',
success: function (response){ getInventory(response,QueryItems) },
error: function (error) {console.log(error);}
});
}
});
});
Java script :
function getInventory(data,queryTarget){
console.log("In Get Inventory Function in javascript ... " +queryTarget)
var queryTarget = "#"+queryTarget
// get the query id
const SelectBoxQuery = document.querySelector(queryTarget)
console.log(SelectBoxQuery)
// resetting the values to enter all the new one.
SelectBoxQuery.options.length = 0; // reset the values
// making a loop to reach each element item in the list
for (var i = 0; i < data.length; ++i) {
// add new element which is option to the targeted ID
var SelectBoxQuery_Addition = document.createElement('option');
// adding a text to that option
SelectBoxQuery_Addition.text = data[i];
// apply the adding .
SelectBoxQuery.add(SelectBoxQuery_Addition)
}}
The problem is, after i get response from python FLASK to Jquery function. in success part it should launch the javascript function with the same i of the queryTargetList.
for example if i pass data[1], i expect to have queryTargetList[1] also.
but in javascript console.log function. that does not happen. it printing the last item of the queryTargetList list.
Print:
Before Launching the Javascript : Item1
JQueryTests.js:11 Before Launching the Javascript : Item2
JQueryTests.js:11 Before Launching the Javascript : Item3
JQueryTests.js:11 Before Launching the Javascript : Item4
operationJavaScript.js:115 In Get Inventory Function in javascript ... Item4
In Get Inventory Function in javascript ... Item4
In Get Inventory Function in javascript ... Item4
In Get Inventory Function in javascript ... Item4
I do not know what am doing wrong :(
Since the ajax call is an async operation, the loop variable i would have changed by the time the success method gets called. There is no guarantee that the i would have reached the end.
You would need to wrap the variables, in a closure so that it success methods gets the correct item.
Sample code not tested.
$(document).ready(function () {
$('#ProvisionLink').click(function () {
var queryTargetList = [ "Item1","Item2","Item3","Item4"]
var data = ["Data1","Data2","Data3","Data4" ]
event.preventDefault();
var i;
for(i = 0; i < queryTargetList.length; ++i) {
var dataItem = data[i];
var QueryItems = queryTargetList[i];
console.log("Before Launching the Javascript : " +QueryItems)
(data,queryItem)=>{
$.ajax({
url: '/operation',
data: {DataType: data,},
type: 'POST',
success: function (response){ getInventory(response,queryItem) },
error: function (error) {console.log(error);}
});
})(dataItem,QueryItems);
}
});
});
set the async option to false:
$.ajax({
url: '/operation',
data: {DataType: dataItem,},
async: false,
type: 'POST',
success: function (response){ getInventory(response,QueryItems) },
error: function (error) {console.log(error);}
});
Another way: send queryTargetList[i] value to server and response get from server..
You must consider the issue of synchronization and non-synchronization, because you did not set the async attribute, so the default will be true. The easiest way is to set the async attribute to false
Like my example below, for detailed usage, you can refer to here
$.ajax({
url: '/operation',
data: {DataType: dataItem,},
type: 'POST',
async: false,
success: function (response){ getInventory(response,QueryItems) },
error: function (error) {console.log(error);}
});
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 4 years ago.
In the following code, I'm running a for loop, which sets a variable 'nets' which is updated for each item within the array netnos[].
Then I call Ajax to process a php to produce a listing, which is correctly being output to response.
I'm setting a variable theList inside the success function, which combines the nets variable with the response. Then appending to my subNets div.
The problem is the 'nets' variable here never updates from its original value, even thou the response is correct. This means the data: {q : nets} does changes correctly.
So why is nets in the success: not being updated? It always retains the value of the first item in the array.
<script>
$(document).ready(function(){
$(document).on('click', '.subnetkey', function() {
var thelist = "";
var strr = $(".subnetkey").val(); // The string of net numbers like 789, 790
var count = strr.split(',').length; // How many are in the string 2 in the test case
var netnos = strr.split(","); // The string made into an array of nets
$("#subNets").removeClass("hidden"); // Remove the hidden from the subNets div
for (i=0; i<count; i++) { // Loop through
var nets = netnos[i]; // Find each net number from the array
// alert('i= '+i+' nets= '+nets); // When i=0 nets = 789, when i=1 nets = 790
$.ajax({
type: "GET",
url: "getactivities.php",
data: {q : nets},
success: function(response) {
var thelist = "#"+nets+"<br>"+response+"<br><br>";
$("#subNets").append(thelist);
},
error: function() {
alert('Sorry no nets.');
}
}) // End of ajax
} // End for loop
}); // End of on(click) function
}); // End of ready function
</script>
The problem is the name nets is lexically bound in the for loop, and its value will change as you iterate i. An easy way to fix this is to use Array.forEach as each invocation of the function it uses for iteration will have its own binding of nets - and it'll lead to shorter code too as you don't even need i!
$(document).ready(function() {
$(document).on("click", ".subnetkey", function() {
var strr = $(".subnetkey").val();
var netnos = strr.split(",");
$("#subNets").removeClass("hidden");
netnos.forEach(nets => {
$.ajax({
type: "GET",
url: "getactivities.php",
data: { q: nets },
success: function(response) {
var thelist = "#" + nets + "<br>" + response + "<br><br>";
$("#subNets").append(thelist);
},
error: function() {
alert("Sorry no nets.");
},
});
});
});
});
Define your nets variable like this and it should work
let nets = netnos[i];
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I spent lot of time to figure this out but did not find anything,
function constructAgenciesData() {
$.ajax({
url: "getAgenciesAndGlobalJson.do",
dataType: "json",
success: function(data){
$.each(data, function (index, row) {
// console.log("data : "+ JSON.stringify(data));
$("#"+row.id).data("assignedAgencies", row.assignedAgencies).data("restOfAgencies", row.restOfAgencies).data("global", row.global).data("globalID", row.globalID);
});
}
});
}
constructAgenciesData();
$(function($){
$(".globalswitch").each(function () {
var idRow = $(this).parents('tr')[0].id;
alert(idRow);
console.log($('#'+idRow).data("global"));// <-- UNDEFINED
$(this).switchButton({
checked: row.data("global")
});
});
$(document).on('click','button.btn', function () {
var idRow = $(this).parents('tr')[0].id;
var title = $(this).parents('td:first').siblings(':eq(1)').text();
title = "Rule Name : " + title;
$("#divPopUp").data('param_1', idRow);
$("#divPopUp").data('opener', this).dialog("option", "title", title).dialog("open");
console.log($('#'+idRow).data("global"));// <-- WORKING
var old_array = $('#'+idRow).data("restOfAgencies");
var new_array = $('#'+idRow).data("assignedAgencies");
addCheckbox(diff(old_array,new_array));
});
});
I don't know why the same line :
console.log($('#'+idRow).data("global"));
is undefined in the .each function.
BUT it is working in the click function .
Your $.ajax call is asynchronous. This means that it is firing request while the rest of the Javascript is being run.
The success function within constructAgenciesData() might not have been completed prior to the IIFE $(function($){.
Therefore, there is no guarantee that the .data('global') will be set by the time you're trying to access it within the $(".globalswitch").each loop.
A solution to this issue would be to wrap the $(".globalswitch").each loop within a function globalSwitchLoop() and fire that on the success of the $.ajax call.
Also, take a look at jQuery's promises.
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 write a JavaScript function that retrieves surname that corresponds to a supplied email address with no success so far. Here's my code:
function getUsername(){
var username;
$(function(){
var dataString = 'email=' + EMAIL_ADDRESS;
$.ajax({
url: 'user_crud_operations.php',
data: dataString,
dataType: 'json',
success: function(data){
U = data[1];
username = data;
}
});
});
return username;
}
I need to use the retrieved username in another function elsewhere. Where am I going wrong?
Asynchronous functions (as used in AJAX) usually do not return values but instead trigger callback functions.
You must restructure your design so that "getUserName()" passes to a callback instead of returning a value. For example:
function getUsername(handler) {
// ...
$.ajax({
// ...
}).done(function(username) {
if (handler && (typeof(handler)==='function')) {
handler(username);
}
});
}
// Sample usage...
getUsername(function(username) {
alert("OK: username=" + username);
});
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to return the response from an AJAX call from a function?
I'm trying to get some HTML content via ajax. But for some reason, though the HTML makes it to the ajax function, when I try to use it as a returned value, I get undefined.
Like this:
function get_additional_options(name) {
var post = $.ajax({
type: 'post',
url: 'order_queries_templates/html/' + name + '_additional_options.php?<?=time()?>',
//data:'product_id=' + product_id,
dataType: 'html'
});
post.done(function (p) {
console.log(p); //prints out all the HTML just as I would expect
return p;
});
}
but when I try to get the HTML to append it to my page like this
if (has_additional_options == "t"){
var html_to_append = get_additional_options(name);
console.log(html_to_append); // undefined
}
It is the same result if I use the done() method, or just return the value as a success callback. What is my error?
You can't return values from asynchronously called functions.
You should return post (i.e. the result of $.ajax) and then register a .done handler outside of your function:
function get_additional_options(name) {
return $.ajax({
...
});
};
if (has_additional_options == "t") {
get_additional_options(name).done(function(p) {
console.log(p);
});
// NB: code execution continues here immediately - don't do anything
// else here - all further stuff must be done in the above callback
}
You are returning the HTML value inside the anonymous function.
You're basically passing it to the post.done method.
Maybe it's better to use events in this case since you're running asynchronous code here.
function get_additional_options(name) {
var post = $.ajax({
type: 'post',
url: 'order_queries_templates/html/' + name + '_additional_options.php?<?=time()?>',
//data:'product_id=' + product_id,
dataType: 'html'
});
post.done(function (p) {
$("body").trigger("html_loaded",[p]);
);
}
$("body").on("html_loaded", function (htmlData) {
// Do something with your HTML data here.
$(this).append(htmlData);
});