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 6 years ago.
I'm currently learning to use API's. I'm retrieving data from my Github repo. I'm trying to have the script load the JSON info into the githubData variable. But when I log the githubData variable to console it returns an empty array.
Yet, if I create a new variable with the exact same function after the page is loaded the script works exactly as it should.
When the page is loading, it's not loading the actual data. It loads an an empty array. I realize the function is asynchronous, so how would I go about getting the array to not be empty when I load the page?
Here's my code:
var githubAPI = 'https://api.github.com/repos/zacharysohovich/ticTacToe/readme';
var items = {};
jQuery.ajax({
url: githubAPI,
contentType: 'application/json; charset=utf-8',
success: function(resultData) {
$.each(resultData, function(key,val) {
items[key] = val;
});
}
});
var githubData = $.map(items,function(k,v) {
return ("<p>" + k + ": " + v + "</p>");
});
The problem is that its an asynchronous call meaning that once it fires of the request it goes onto the next piece of code. Once it gets to githubData items is still an empty object because the api response hasn't been received yet.
I would instantiate the githubData variable right below var items = {}
like so
var items = {}
var githubData;
and then in the success: function after you do the $.each you can put the
githubData = $.map(items,function(k,v) {
return ("<p>" + k + ": " + v + "</p>");
});
this ensures that the api call has finished and items should have something in it as long as the response came back with something
Related
This question already has answers here:
Sending multipart/formdata with jQuery.ajax
(13 answers)
Closed 3 years ago.
I want to pass imageArray[] along with a variable trackNo. The imageArray[] I can pass it fine with no problem. I'm just uncertain on how to append/include other variables to the FormData()
Online I only see examples of people passing only a file array to a php file and never with other information.
$('#ad_post_btn').click(function () {
ad_errmsg = "";
imageList = myImageList(); //my array of images imageList[]
console.log(imageList); //display files in imageList[]
var trackNo = Math.round(Math.random() * (100000 - 1) + 1); // random number
console.log(trackNo); // shows the random generated number
var data = new FormData();
var dataString = 'trackno=' + trackNo; //the variable a want to pass along with the array
for (var i = 0; i < imageList.length; i++) {
data.append('images[]', imageList[i]); //where I store my image files, work fine
}
$.ajax({
url: 'uploadimage.php',
type: 'post',
data: data,
contentType: false,
processData: false,
success: function (data) {
console.log(data);
}
});
I've tried
data: data,dataString ,
Thank you for your time
Solution:
data.append("key", value);
Source:
https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
data.append('trackno', trackNo);
You can put this right before or after your for loop.
.append('key', value) will allow you to keep adding more fields.
https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
I've read a good bit about callbacks, and while I use them for click events and similar, I'm using them without fully understanding them.
I have a simple web app with 3 or 4 html pages, each with its own js page.
I have some global functions that I've placed in a new js page which is referenced by each html page that needs it. I'm using this file, word_background.js, to hold functions that are lengthy and used by multiple pages.
pullLibrary is a function, residing in word_background.js, that pulls from my db and processes the results.
I want to call pullLibrary from webpageOne.html, make sure it completes, then do more processing in webpageOne.js.
In webpageOne.js I have the following - trying to call pullLibrary and, once it is complete, use the results for further work in webpageOne.js.
The code executes pullLibrary (in word_background.js) but doesn't "return" to webpageOne.js to continue processing.
I'm assuming I'm missing some critical, essential aspect to callbacks...
I just want to run the pullLibrary function (which has ajax calls etc) and, once it is complete, continue with my page setup.
Any explanation/correction appreciated.
This code is in webpageOne.js:
pullLibrary(function(){
console.log('Now processing library...');
processLibrary();
updateArrays();
//Do a bunch more stuff
});
----- UPDATE -----
Thank you for the comments...which I think are illuminating my broken mental model for how this should work.
pullLibrary is an ajax function - it pulls from a database and stuffs the results into an array and localStorage.
My expectation is that I can call pullLibrary and, when it is complete, the callback code (in this case anonymous function) will run.
function pullLibrary(){ //Values passed from startup() if no data is local
//Pull data from database and create basic LIBRARY array for further processing in processLibrary sub
console.log("Starting to pull library array in background.js..." + "User: " + localStorage.userID + " License: " + localStorage.licType);
var url1 = baseURL + 'accessComments3.php';
var url2 = '&UserID=' + localStorage.userID + '&LicType=' + localStorage.licType;
//Need global index to produce unique IDs
var idIndex = 0;
var index = 0;
$.ajax({
type: "POST",
url: url1,
data: url2,
// dataType: 'text',
dataType: 'json',
success: function(result){
// success: function(responseJSON){
arrLibrary = result; //store for use on this page
localStorage.library = JSON.stringify(result); //Store for use elsewhere
console.log('Saving to global variable: ') + console.log(arrLibrary);
//Now mark last update to both sync storage and local storage so access from other browsers will know to pull data from server or just use local arrays (to save resources)
var timeStamp = Date.now();
var temp = {};
temp['lastSave'] = timeStamp;
// chrome.storage.sync.set(temp, function() {
console.log('Settings saved');
localStorage.lastSync = timeStamp;
console.log('Last update: ' + localStorage.lastSync);
//Store Group List
var arrComGroups = $.map(arrLibrary, function(g){return g.commentGroup});
// console.log('List of comment groups array: ') + console.log(arrComGroups);
arrComGroups = jQuery.unique( arrComGroups ); //remove dupes
// console.log('Unique comment groups array: ') + console.log(arrComGroups);
localStorage.groupList = JSON.stringify(arrComGroups); //Store list of Comment Groups
//Create individual arrays for each Comment Groups
$.each(arrComGroups,function(i,gName){ //Cycle through each group of Comments
var arrTempGroup = []; //to hold an array for one comment group
arrTempGroup = $.grep(arrLibrary, function (row, i){
return row.commentGroup == gName;
});
//Store string version of each Comment Array
window.localStorage['group_' + gName] = JSON.stringify(arrTempGroup);
console.log('Creating context menu GROUPS: ' + gName);
});
// processLibrary(arrLibrary); //We've pulled the array with all comments - now hand off to processor
}, //End Success
error: function(xhr, status, error) {
alert("Unable to load your library from 11trees' server. Check your internet connection?");
// var err = eval("(" + xhr.responseText + ")");
// console.log('Error message: ' + err.Message);
}
}); //End ajax
}
Okay, there are tons of "here's how callbacks work" posts all over the internet...but I could never get a crystal clear example for the simplest of cases.
Is the following accurate?
We have two javascript files, one.js and two.js.
In one.js we have a function - lets call it apple() - that includes an Ajax call.
two.js does a lot of processing and listening to a particular html page. It needs data from the apple() ajax call. Other pages are going to use apple(), also, so we don't want to just put it in two.js.
Here's how I now understand callbacks:
one.js:
function apple(callback_function_name){
$.ajax({
type: "POST",
url: url1,
data: url2,
dataType: 'json',
success: function(result){
//apple processing of result
callback_function_name(); //This is the important part - whatever function was passed from two.js
}, //End Success
error: function(xhr, status, error) {
}
}); //End ajax
} //End apple function
** two.js **
This js file has all kinds of listeners etc.
$(document).ready(function () {
apple(function(apple_callback){
//all kinds of stuff that depends on the ajax call completing
//note that we've passed "apple_callback" as the function callback name...which is stored in the apple function as "callback_function_name".
//When the ajax call is successful, the callback - in this case, the function in two.js, will be called back...and the additional code will run
//So the function apple can be called by all sorts of other functions...as long as they include a function name that is passed. Like apple(anothercallback){} and apple(thirdcallback){}
}); //End apple function
}); //End Document.Ready
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I've been trying for hours to get this to work, but it's just not budging; I have the following code:
var text = "";
function getText(c1, c2)
{
url = "http://en.wikipedia.org/w/api.php?format=json&action=query&titles=" + c1 + "-" + c2 + "_relations&prop=revisions&rvprop=content"
$.ajax({
type: "GET",
dataType: "jsonp",
async: false,
url: url,
success: function (data) {
var obj = (data.query.pages );
var keys = [];
for(var k in obj) keys.push(k);
if (keys[0] == -1) {
//Link doesnt exist
text = "-1";
return text;
}
//Link Exists
else {
link = "http://en.wikipedia.org/wiki/" + c1 + "-" + c2 + "_relations"
text = c1 + "-" + c2 + " Relations"
return text;
}
}
});
return text;
}
var a = (getText(country1, country2))
alert(text);
alert(a);
I'm making an ajax request; a simple inquiry to see if wiki has a page between any 2 given countrie.
If I use alert inside, it works fine, and it returns the correct data inside the text variable. However, when the getText function is called outside, the text variable is always empty. I've tried everything I can think of, including getting the app to sleep for some time, but even that didn't work. I know the async doesn't work from ajax 1.8 onwards, but is there anyway around this?
Thanks in advance.
It is because the asynchronous behavior of ajax. You can't return values from ajax like this way. Because the function will not wait for the success event to happen.
When you put an alert inside that function, success event may occur before the user clicks on alert. That is why it returning value. Otherwise it will not return the value.
Its not a good practice to use async : false in ajax calls. It will freeze the browser.
Good practice is to call a method from the ajax success with the returned data, then do operations with that data inside the function.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
This is makinkg me crazy, i cant Get the outside variable Get the inside data
Sorry for the bad formating I'm writing from the phone, if someone can helpme out with the format I appreciate it
window.getReasons = function(line) {
var $reasons;
$reasons = "";
$.get(window.location.protocol + "//" + window.location.host + "/" + "allLineReasons.js?line=" + line, function(returnData) {
$reasons = returnData.toString();
return console.log("T_T ----->" + returnData.toString());
}, "html");
console.log($reasons);
return $reasons;
};
The most important thing for you to understand is that $.get() is ASYNCHRONOUS by default. So what is happening is that your console.log() and return statements that follow your call to get() are executing before the get() has returned it's value.
You might look to utilize the when() method here to handle the deferred object that is returned from get()
window.getReasons = function(line) {
var reasons = '';
$.when(
$.get(window.location.protocol + "//" + window.location.host + "/" + "allLineReasons.js?line=" + line)
).done(function(jqxhr) {
data = jqxhr[0];
reasons = data.toString();
});
console.log(reasons);
return reasons;
}
$reasons won't be updated until after the GET completes on the server and the response is returned. But your console.log will execute immediately after the request is made.
I'm having trouble getting my information into an array in an ajax call, if I alert the information right after I insert it into the array it works fine, but if I do it at the end it alerts unidentified. I made sure that books is declared outside so it doesn't interfere.
var books = [];
$.ajax({
url: 'getFolderContents.php',
dataType: 'json',
success: function (data)
{
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
}
},
error: function()
{
alert("error");
}
});
alert(books[0]);
Your
alert(books[0]);
will be executed while the Ajax call is running and therefore will not have any elements at this point of execution yet. Ajax is asynchronous - while you are doing a request to your PHP script your script continues execution.
Put all actions with books in your success function.
Another hint: As of jQuery version 1.8 you cannot longer use the parameter async: false to create a synchronous "A"jax call. You have to use the callback functions. Have a look at the docs for $.ajax
Your array hasn't lost any data; the data hasn't been put in there yet. The 'A' stands for "asynchronous", meaning your success callback hasn't run yet at the time you call the alert.
Put the alert inside your callback instead:
success: function (data)
{
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
}
alert(books[0]);
},
Your alert is executing before the success function is called. Perhaps seeing the same code using a promise will make things clearer.
$.ajax( url: 'getFolderContents.php', dataType: "json" )
//the then function's first argument is the success handler
.then(function( data ) {
for(var i=0;i<data.length;i++) {
var amm = 0;
if(data[i].indexOf(".epub") !== -1) {
//$('#bTable').append("<td><a id = '" + data[i] + "' href = 'book.html'><img src = 'book.png' width = '100px'/><br/>" + data[i] + "</a></td>");
books.push(data[i]);
//alert(books[0]) Works if I call it from here, but not at the end.
}
alert(books[0]
});
});
I always feel this syntax makes async stuff make more sense. Otherwise this code functions exactly like Blazemonger's correct answer.
Your AJAX call is asynchronous, that's why it is undefined.
The alert at the end happens before the ajax success callback, because ajax is asynchronous.