I have a built a php backend which returns a JSON object (effectively a 2D array, I can reference it as json[0][0]
for example, I don't know why though, I did not parse the JSON object) of information(train number, days it runs on etc) on trains between two stations.
Now what I want to query the availability of each train. I already have the php script for that (which returns a JSON object as well, giving the availability of the specified date as well as the next 5 days.).
This availability php script requires some input which is present as the first element of every nested(wrong term to use ?) array eg : json[0][0], json[1][0], json[2][0]
if 3 trains are returned
I want this information returned as a response to parallel ajax calls. In the end I want to create a table based on these responses. My problems are:
I have just begun coding the function, and have something like this, yes I am an utter novice with JS and jQuery :
$(document).ready(function() {
$("form").submit(function(){
event.preventDefault();
$.ajax({
//type: "POST",
url: "./trains_bw_stations.php",
dataType: 'json',
data: { source: $('input[name*="src"]').val(), destination: $('input[name*="dstn"]').val(),
day: $('input[name*="day"]').val(), month: $('input[name*="month"]').val(), cl: $('input[name*="cl"]').val() }
})
.done(function(trains) {
console.log(trains)
var requests = [], allData = {};
for (var i = 0; i < trains.length; i++) {
console.log(trains[i][0]);
requests.push($.ajax({
url: './availability.php',
dataType: 'json',
data: {
day: $('input[name*="day"]').val(), month: $('input[name*="month"]').val(),lccp_trndtl: trains[i][0] }
// success: function(data) {
// console.log(data);
// allData[''+i] = data;
}).done(function(data) {
console.log(data);
allData[i] = data})
);
}
$.when.apply(requests).then(function() {
console.log(allData) // this is line 41
}
// all requests have completed
// allData array now contains the data from all the requests
// put your processing logic in here...
});
});
});
});
allData remains empty ! console output :
XHR finished loading: GET "http://localhost/irl_poster/trains_bw_stations.php?source=ndls&destination=hyb&day=7&month=8&cl=SL". jquery-2.1.1.min.js:4
[Array[15], Array[15], Array[15]]
ajaxRequests.js:19
12650NZM KCG YYYNYNYYA ajaxRequests.js:23
12724NDLSHYB YYYYYYYYA ajaxRequests.js:23
12722NZM HYB NYYYYYYYA ajaxRequests.js:23
Object {} ajaxRequests.js:41
XHR finished loading: GET "http://localhost/irl_poster/availability.php?day=7&month=8&lccp_trndtl=12650NZM+KCG+YYYNYNYYA". jquery-2.1.1.min.js:4
Object {0: Array[4], 2: Array[4], 4: Array[4], 6: Array[4], 8: Array[4], 10: Array[4]}
ajaxRequests.js:34
XHR finished loading: GET "http://localhost/irl_poster/availability.php?day=7&month=8&lccp_trndtl=12724NDLSHYB+YYYYYYYYA". jquery-2.1.1.min.js:4
Object {0: Array[4], 2: Array[4], 4: Array[4], 6: Array[4], 8: Array[4], 10: Array[4]}
ajaxRequests.js:34
XHR finished loading: GET "http://localhost/irl_poster/availability.php?day=7&month=8&lccp_trndtl=12722NZM+HYB+NYYYYYYYA". jquery-2.1.1.min.js:4
Object {0: Array[4], 2: Array[4], 4: Array[4], 6: Array[4], 8: Array[4], 10: Array[4]}
You have an error in your $.when.apply
call - it needs an initial context parameter, typically $
Your code also suffers the common problem of using the loop variable i
from inside an asynchronous callback at which point it no longer retains its original value and the results all end up in allData[trains.length + 1]
So, instead of trying to accumulate allData[i]
in the .done
callback you can remove that .done
call altogether, and then within the .when().then()
callback you can use the arguments
array to access the individual results, which will automatically appear in the correct order:
$.when.apply($, requests).then(function() {
// convert the arguments array, where each argument is in the form
// [data, textStatus, jqXHR], into an array of just the data values
var allData = [].map.call(arguments, function(arg) {
return arg[0];
});
...
});
The initial request loop can also be slightly simplified using Array.prototype.map
:
var requests = trains.map(function(train) {
// no "i" variable needed - use "train" instead of "train[i]"
return $.ajax({
...
});
});
You are correct that you need to use $.when
, although your syntax is a little off. Try this:
.done(function(json) {
var requests = [], allData = [];
// loop over your result, amend as needed
for (var i = 0; i < json.length; i++) {
requests.push($.ajax({
url: 'foo.html', // build as needed using properties of json
success: function(data) {
allData.push(data);
}
}));
}
$.when.apply(requests).then(function() {
// all requests have completed
// allData array now contains the data from all the requests
// put your processing logic in here...
});
});
If you need to maintain the order of the data received, you could change the allData
variable to an object, keyed by the index of the loop:
// note: amended lines only
var requests = [], allData = {};
success: function(data) {
allData[i] = data;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.