variable assignment inside ajax success call not working - javascript

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?

Related

Symfony : Add data from Ajax call to js array

I have an Ajax request that fetch data in database.
These data may vary in function of the action that calls the ajax request.
Each time the Ajax request is called, I want some ot these datas to be pushed in a javascript array declared outside of the Ajax function.
The problem is, each time Ajax is called, my function manage to put the wanted data in the array but erases the previous data.
Here is the script :
<script>
let myArray = [];
function fetchWeeksForViewportWidth(startDate) {
//AJAX
$.ajax({
method: "GET",
url: "{{path('days_json')}}",
data: {
//some data
},
success: function (data) {
let trParents = document.getElementsByClassName('project-assignment');
$.each(trParents, function(key, parent) {
let assId = parent.dataset.assignmentId;
myArray[assId] = [];
$.each(data['days'], function(key, value) {
myArray[assId][value.code] = 0;
//some other treatment
if(value.code in data['game']) {
myArray[assId][value.code] = data['game'][value.code];
});
});
});
},
error: function() {
//handle error
console.log("error")
}
});
}
$(document).ready( function () {
function displayArray(){
console.log(myArray);
setTimeout(displayArray, 5000);
}
displayArray();
});
</script>
Any idea why new data don't add to the ones from previous ajax calls but keep replacing them ?
Instead of assignment
myArray[assId][value.code] = 0;
try the push() function of the array
myArray[assId].push(0);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

getting data from file.txt and returning it with an array

i have file.txt
apple <--line 1
banana <--line 2
and this is my script
url = 'file.txt';
homelists = [];
$.get(url, function(data) {
var lines = data.split("\n"); <--i want to split it by line
$.each(lines, function(n ,urlRecord) {
homelists.push(urlRecord); <--add it to my homelists array
});
});
console.log(homelists); <-- returns array
console.log(homelists[0]); <--undefined
my problem is i cant get the inside value of homelists
how can i get homelists[0] or homelists[1]..(javascript or jquery(preferrable))
Javascript/Jquery ajax is an Async call meaning the code $.get and console.log on your example will be executed parallelly (immediate or the same times), so to parse the result of your file.txt, you need to do it inside the function (which will be executed after ajax called is done).
url = 'file.txt';
homelists = [];
$.get(url, function(data) {
var lines = data.split("\n");
$.each(lines, function(n ,urlRecord) {
homelists.push(urlRecord);
});
console.log(homelists);
console.log(homelists[0]);
});
I know this is too simple answer and may sound stupid to others but i have an idea!
why not store in the session the $.get data
url = 'file.txt';
$.get(url, function(data) {
localStorage['homelists'] = data;
});
then assign a variable to that session
homelists = localStorage['homelists'];
then make the session = null
localStorage['homelists'] = null
when you do console.log outside
console.log(homelists); <-returns string which you can manipulate to turn it into array
console.log(localStorage['homelists']); <-returns null
I dont know yet what could be the bad side/effect of this with my project.. any idea?
Since you are using jQuery, It would be better if you use AJAX. !
const ImportData = function(file){
let arrayData = undefined;
$.ajax({
url: file,
type: 'GET',
error: (err) => { throw new Error(err) },
success: ( data ) => {
arrayData = MakeArray( data );
//Do whatever you want here
console.log( arrayData );
}
});
}
const MakeArray = function(plaintext){
const array = [];
plaintext.split('\n').forEach( (line) => {
line = line.trim();
array.push( line );
} );
return array;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
const file = "https://www.w3.org/TR/PNG/iso_8859-1.txt";
document.addEventListener('DOMContentLoaded', function(){
ImportData( file );
});
</script>

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 display array content at the end of getjson call?

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.

Populating array with response from nested AJAX calls

I have an array that I would like to fill with responses from AJAX calls like so:
var dict = [];
function fillArray(){
$.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++){
$.get("https://api.twitch.tv/kraken/streams" , function(data){
dict[data.key] = data;
});
});
}
function doStuff(){
// dict is empty or undefined here
}
How would I fill dict with objects so that I could retrieve them inside doStuff()? Currently, I am able to insert stuff into dict but when I try accessing dict outside the fillArray() function, I get an empty dict variable since I'm assuming the GET call is asynchronous and doesn't happen until after all the JS code has executed...
So, dict is an object that has no push method. You'd need dict=[]; If you had to have {}, then you'd need key:value pairs to populate it, such as:
dict[key] = value;
You are going to have to keep track of the number of calls that you are doing in that for loop and fire a callback function once they are all complete. I'm not totally confident about your current solution, with calling an indefinite amount of ajax requests, but I also don't fully understand the scope of your problem or the server that you're talking to.
So basically you will have to do something like this with what you have currently:
var dict = [],
requestsCompleted = 0;
function dictFilled() {
// do something with your dict variable;
}
function fillArray(){
$.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++){
$.get("https://api.twitch.tv/kraken/streams" , function(data){
dict[data.key] = data;
requestsCompleted++;
if (requestsCompleted === phpReturnVal.length) {
dictFilled();
}
});
});
}
This haven't been tested, but basically you will have to define a function that will have access to the array that you are filling and call it once all you asynchronous requests finish successfully. For tasks like this though I recommend you take a look at jQuery's Deferred API. There is always a chance that one of those requests will fail and your application should know what to do if that happens.
I'm assuming the GET call is asynchronous and doesn't happen until
after all the JS code has executed...
Appear correct.
Try
var dict = [];
function fillArray() {
// return jQuery promise object
return $.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++) {
// call same `url` `phpReturnVal.length` times here ?,
// returning same `data` response at each request ?,
// populating, overwriting `dict` with same `data.key` property ?
$.get("https://api.twitch.tv/kraken/streams" , function(data) {
dict[data.key] = data;
});
}; // note closing `}` at `for` loop
// return value
return dict
});
}
function doStuff(data) {
// `data`:`dict`, promise value returned from `fillArray`
console.log(data);
}
fillArray().then(doStuff, function error(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown)
});
var arr = ["a", "b", "c"];
var response = {
"a": 1,
"b": 2,
"c": 3
};
var obj = {};
var dict = [];
function fillArray() {
return $.when(arr).then(function(phpReturnVal) {
for (var i = 0; i < phpReturnVal.length; i++) {
// return same `response` here ?
$.when(response).then(function(data) {
dict[arr[i]] = data;
});
};
return dict
});
}
function doStuff(data) {
console.log(data)
}
fillArray().then(doStuff, function error(err) {
console.log(err)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

Categories