How to display array content at the end of getjson call? - javascript

i have a function that makes 2 getjson calls and writes the responses to an array . i used the following code at the end of my second getjson call:
alert(files.length);
print_r(files);
console.log(files);
However , the files.length tells me the number of items in the array but print_r(files); and console.log are not working ? i want to print the array items to confirm i got correct items but array print doesn't work ! could any one tell me how to fix this problem ?( my goal is to later on sort this array and remove duplicates and filter... )
<script>
var files = new Array();
function pushtoArray(){
//first getjson call
var url1 = "https://spreadsheets.google.com/feeds/list/xxxxx/xxxxx/public/values?alt=json";
$.getJSON(url1, function(data) {
var entry = data.feed.entry;
$(entry).each(function(){
// Column names are name, age, etc.
count++;
files.push({ url: this.gsx$url.$t, filename: this.gsx$name.$t });
$('.results').prepend('<h2>'+this.gsx$name.$t+'</h2><p>'+this.gsx$url.$t+'</p>');
});
alert(files.length);
print_r(files);
console.log(files);
});//end of ajax call
//second getjson call
var url2 = "https://spreadsheets.google.com/feeds/list/xxxxx/xxxxx/public/values?alt=json";
$.getJSON(url2, function(data) {
var entry = data.feed.entry;
$(entry).each(function(){
// Column names are name, age, etc.
count++;
files.push({ url: this.gsx$url.$t, filename: this.gsx$name.$t });
$('.results').prepend('<h2>'+this.gsx$name.$t+'</h2><p>'+this.gsx$url.$t+'</p>');
});
alert(files.length);
print_r(files);
console.log(files);
});//end of ajax call
};//end of function
</javascript>
html code:
<body onload="pushtoArray()">

Print_r is a PHP function, in javascript you can only use console.log.

Related

variable assignment inside ajax success call not working

I am trying to collect data from a ajax request from a buch of URLs doing something like this:
let allData = [];
let dataURL = [];
$('.pagn .pg').each(function(){
if($(this).attr('data-url')){
dataURL.push("https://www.myweb.com/" + $(this).attr('data-url'));
}
})
//dataURL.shift() //Remove first item from array
dataURL.splice(dataURL.length-1,1); //Remove last item from array
console.log(`COLLECTED URL`)
console.log(dataURL)
for(let i = 0;i<dataURL.length;i++){
console.log(`Inside Loop`)
getAndPopulateData(dataURL[i],i)
}
function getAndPopulateData(dataUrl,removeIndex){
console.log(`Inside Ajasx`)
$.ajax({
type:"GET",
url:dataUrl,
success:function(data){
console.log(`Ajax successful`)
console.log(data.data.items)
allData.push(data.data.items)
dataURL.splice(removeIndex,1);
if(dataURL.length == 0){
console.log(`All elements have been removed`)
}
}
})
}
I can see the data in my console coming from console.log(data.data.items) which takes about 2 seconds to appear. But when I check the allData variable it is just an empty array. Shouldn't everything inside the success function be processed synchronously?

jQuery each loop variable data lost [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
having a little trouble with my variable scope in jQuery, how come if I do the console.log outside the .each loop I get an empty array on $stockData ? (if i do it inside the .each, it works just fine, logs the array each time a value is added)
$(document).ready(function(){
// stock data will contain all the merged data from the database and yahoo queries
var $stockData = new Array();
// get data from yahoo and merge with dbData, add to stockData array
$.getJSON( "/get_portfolio.php", function(dbData) {
$.each( dbData, function(index) {
var stock = dbData[index]
$.ajax({
url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%3D%22"+stock.stock_symbol+"%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys",
crossDomain: true
}).success(function(data){
var quote = data.query.results.quote;
$.extend(quote, stock);
$stockData.push(quote);
}); // end success
});// end each
}); // end getJSON
console.log($stockData);
}); // end document.ready
when you call
$.getJSON( "/get_portfolio.php", function(dbData) { ... });
this part:
function(dbData) { ... }
doesn't run right away. JavaScript says: "oh you did a http request? I'll hold onto this function you gave me and run it after the request is done". And the rest of your code will keep on running, so this:
console.log($stockData);
will run first. So the actual order of execution here is:
you run getJSON
console.log runs
the HTTP request finishes and your callback runs
put the console.log inside the getJSON block, right after your .each loop:
$(document).ready(function(){
// stock data will contain all the merged data from the database and yahoo queries
var $stockData = new Array();
// get data from yahoo and merge with dbData, add to stockData array
$.getJSON( "/get_portfolio.php", function(dbData) {
var requestsDone = 0;
$.each( dbData, function(index) {
var stock = dbData[index]
$.ajax({
url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%3D%22"+stock.stock_symbol+"%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys",
crossDomain: true
}).success(function(data){
var quote = data.query.results.quote;
$.extend(quote, stock);
$stockData.push(quote);
if(++requestsDone == dbData.length) done();
}).error(function(){
if(++requestsDone == dbData.length) done();
});
});// end each
function done() {
console.log($stockData); // put this here
}
}); // end getJSON
}); // end document.ready
You need to wait getJSON function be completed, try this:
$(document).ready(function(){
// stock data will contain all the merged data from our database and yahoo queries
var $stockData = new Array();
// get data from yahoo and merge with dbData, add to stockData array
$.getJSON( "/get_portfolio.php", function(dbData) {
$.each( dbData, function(index) {
var stock = dbData[index]
$.ajax({
url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%3D%22"+stock.stock_symbol+"%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys",
crossDomain: true
}).success(function(data){
var quote = data.query.results.quote;
$.extend(quote, stock);
$stockData.push(quote);
}); // end success
});// end each
console.log($stockData);
}); // end getJSON
});

How to read XML data with $.ajax and return the value within a $.each loop

For one part of our study-project we need to compare an array of Strings with a xml database. So my idea was to divide in 2 parts (because we need the compare-function twice). First I loop through the array with $.each and then I pass the value to another function that makes an ajax request to the xml, compares the value with each data in xml and if something found, it pushes it to an array which should be returned at the end.
In one function the jquery.each() is called:
function doSomething(){
liste = ["test1","test32","test22"];
$.each(liste, function(index, value){
var checkIt = compareDataBase(value);
if(checkIt.length>0) //do Something
});
}
and this is the function that compares the value and returns an array:
function compareDataBase(foo){
var lists = [];
$.ajax({
type:"GET",
url: "data/database/datenbank.xml",
dataType:"xml",
success: function(xml){
$(xml).find('product').each(function(index, element){
var current_product = $(this).text();
if(current_product.indexOf(foo)>-1)lists.push(current_product);
});
},
error: function(){
console.log("Fehler bei Produkte auslesen");
}
});
return lists;
}
But sadly that doesn't work. "checkIt" is always undefined because it doesnt wait for the ajax...
I tried to use the $.when function or give the compareDataBase()-function a callback but somehow that didnt work neither (I think because
I declared it wrong)
So maybe someone knows how to make this right?
Thanks for your help!
br sebi
You should use callbacks (or promises which are a variation on callbacks), the following solution example uses callbacks:
function compareDataBase(foo, callback){
var lists = [];
$.ajax({
type:"GET",
url: "data/database/datenbank.xml",
dataType:"xml",
success: function(xml){
$(xml).find('product').each(function(index, element){
var current_product = $(this).text();
if(current_product.indexOf(foo)>-1)lists.push(current_product);
});
// notify the callback with the result lists here
callback(lists);
},
error: function(){
console.log("Fehler bei Produkte auslesen");
}
});
}
function doSomething(liste, index){
if ( index < liste.length )
{
compareDataBase(liste[index], function(checkIt){
if(checkIt.length>0) //do Something
// process next list item using callbacks
doSomething(liste, index+1);
});
}
}
// start the process
doSomething(["test1","test32","test22"], 0);
Note that the example solution processes each list item only after the previous item has been processed (it kind of synchronises the callbacks, each callback will call the next one). One can remove this feature and process all asynchronously as follows:
// process all async
var liste = ["test1","test32","test22"];
for (var i=0; i<liste.length; i++) doSomething([liste[i]], 0);

Sorting multiple API's by price in a table

This is going to be confusing but probably an easy answer.
I have two api links in a json format. Pulling data into a table.
At the moment, all of the API1 is being put in the table first and below that API2 is then being put in.
Both of the api's have prices in £XX.XX format.
What I am looking for is the table to be sorted by price. So that for example API1 first 2 results are the cheapest, then API2 then API1 and so on and so forth.
I have posted my code below for you to look at.
Table.html
<table class="pull-left table-fill" id="Bananna">
<thead>
<tr>
<th class="table-hover">Vendor</th>
<th class="table-hover">Section</th>
<th class="table-hover">Amount Of Tickets</th>
<th class="table-hover">Price Per Ticket</th>
<th class="table-hover">Link</th>
</tr>
</thead>
</table>
</body>
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="js/1.js"></script>
<script src="js/2.js"></script>
1.js and 2.js are exactly the same.
$.ajax({
type: 'GET',
crossDomain: true,
dataType: 'json',
url: 'API LINK HERE',
success: function (json) {
//var json = $.parseJSON(data);
for(var i =0;i < json.results.length;i++) {
var section = json.results[i].section;
var no = json.results[i].avalible;
var price = json.results[i].price;
var button = "<button class='redirect-button' data-url='viagogo.com'>Compare</button>";
$("#Bananna").append("<tbody><tr><td>"+section+"</td><td>"+no+"</td><td>"+price+"</td><td>"+button+"</td></tr></tbody>");
$("#Bananna").find(".redirect-button").click(function(){
location.href = $(this).attr("data-url");
});
}
},
error: function(error){
console.log(error);
}
});
Don't touch the table until you've got both result sets, that's just going to make sorting more difficult. Define some global results array and populate it with the AJAX data using concat.
var results = [];
//on success of each AJAX call
results = results.concat(json.results);
To ensure both sets of data have been loaded before sorting just include the second AJAX call in the complete function of the first or use recursion if you may have additional AJAX requests in the future.
After you have all the data you can sort by price:
results.sort(function(a,b){
return a.price-b.price;
});
Finally, step through the sorted array and append as you did before.
EDIT:
Instead of making a bunch of files which are all identical, define a recursive function to load an array of API urls like this:
function loadURLs(urls,callback){
//are there more urls to AJAX?
if(urls.length==0){
//no: call the callback function
callback();
}else{
//yes: make the AJAX call...
$.ajax({
type: 'GET',
crossDomain: true,
dataType: 'json',
url: urls[0],
success: function (json) {
//put data into the results array
results = results.concat(json.results);
//load the remaining urls
loadURLs(urls.slice(1),callback);
}
}
}
}
This function accepts an array of URL links. It will go through one by one and load the json data into the global results array. After it has gone through all the links it will call the callback function. Inside the callback function you can sort your array once and then append to your table. Your final js would look something like this:
//define loadURLs function here
//global results array
var results = [];
//define all your links links here
var myURLs = ['API LINK 1','API LINK 2'];
loadURLs(myURLs,function(){
//all json data has been loaded, sort
results.sort(function(a,b){
return a.price-b.price;
});
//iterate over the sorted array and append
for(var i=0;i<results.length;i++){
//append to table
}
});

Code not adding object to an array

I'm trying to add a set of objects that have been retrieved from a JSON file into an array. I've tried using push but the result is the same. The length value of the array remains 0. What am I doing wrong? The JSON parses fine as I can get the values during the loop.
<script type="text/javascript">
//my array
var myArray = new Array();
function performSearch(){
var url = "http://myjsonurl...";
var counter = 0;
$.getJSON(url, function(response){
$.each(response.data.people, function() {
//p is the the object to add to the array
var p = new person(this.name, this.age);
//tried using myArray.push instead of having a counter, but
//I get the same length of 0.
myArray[counter] = p;
counter++;
});
});
//always returns 0
alert(myArray.length);
}
...
</script>
getJSON() is an asynchronous function. It only starts to fetch the data when you call it, and it calls the given function only after it has loaded it. So you call the alert before anything is fetched. You should have the alert right after the .each() function.
Ajax is asynchronous. Whatever depends on the JSON needs to happen in the callback.
function performSearch()
{
var url = "http://myjsonurl...";
$.getJSON(url, function(response)
{
var myArray = $.map(response.data.people, function()
{
return new person(this.name, this.age);
});
alert(myArray.length);
});
//always returns 0
alert(myArray.length);
// that's because this code executes before the $.getJSON callback does
}
You are returning the array before you put the objects in it.
The callback function used in the getJSON method doesn't run right away, it runs when the response arrives. As two methods can't run at the same time, you will always have exited your function before the callback function can run.
You can access the result inside the callback function:
<script type="text/javascript">
function performSearch(){
var url = "http://myjsonurl...";
$.getJSON(url, function(response){
var myArray = [];
$.each(response.data.people, function() {
var p = new person(this.name, this.age);
myArray.push(p);
});
alert(myArray.length);
});
}
</script>
<script type="text/javascript">
//my array
var myArray = new Array();
var counter = 0;
function performSearch(){
var url = "http://myjsonurl...";
$.getJSON(url, function(response){
$.each(response.data.people, function() {
//p is the the object to add to the array
var p = new person(this.name, this.age);
//tried using myArray.push instead of having a counter, but
//I get the same length of 0.
myArray[counter] = p;
counter++;
alert(myArray.length);
});
});
}
...
</script>

Categories