1

I have a function which append some elements if a json file was loaded:

function loadNdraw(title, id){
 $("#containerCharts").html("");
 var date = $("#dateChart");
 var jqJSON = $.getJSON("charts/" + id + "/" + date.val() + ".json");
 jqJSON.done(
 function(data){
 $("#containerCharts").append(
 "<div class='divStandard'>"
 + "<div class='titleChart'>"
 + "<div style='float: left;'>" + title + "</div>"
 + "<div style='float: right;'>" + data.lastUpdate +"</div>"
 + "<div style='clear: both;'></div>"
 + "</div>"
 + "<center><div id='" + id + "' class='bodyChart'></div></center>"
 + "</div>"
 );
 }
 );
}

I call this function multiple times

loadNdraw("A", "a");
loadNdraw("B", "b");
loadNdraw("C", "c");
loadNdraw("D", "d");

My problem is that it does not load in this order.

Every time the page is loaded, the order of A,B,C,D is random.

How can I force it to be loaded in order?

I don't want to sort json.

asked Dec 7, 2018 at 10:14
1

2 Answers 2

3

You can use .promise() function in jquery

function loadNdraw(title, id){
 var dfd = jQuery.Deferred();
 $("#containerCharts").html("");
 var date = $("#dateChart");
 var jqJSON = $.getJSON("charts/" + id + "/" + date.val() + ".json");
 jqJSON.done(
 function(data){
 $("#containerCharts").append(
 "<div class='divStandard'>"
 + "<div class='titleChart'>"
 + "<div style='float: left;'>" + title + "</div>"
 + "<div style='float: right;'>" + data.lastUpdate +"</div>"
 + "<div style='clear: both;'></div>"
 + "</div>"
 + "<center><div id='" + id + "' class='bodyChart'></div></center>"
 + "</div>"
 );
 }
 );
 dfd.resolve(true);
}

Then you can simply call

$.when( loadNdraw("A", "a") ).then(
 $.when( loadNdraw("B", "b") ).then(
 //Some code 
 );
);

You can simply use .promise as per your need

KunLun
3,2864 gold badges32 silver badges93 bronze badges
answered Dec 7, 2018 at 10:27
Sign up to request clarification or add additional context in comments.

Comments

2

The JSON scripts are being loaded asynchronously. The order in which the callbacks fire don't depend on the order in which you invoke loadNdraw, but the order in which jqJSON.done gets fired. The file that loads the fastest will cause its jqJSON.done method to be called first, and so on.

If you need these to be in order, you have a few options:

  1. Sort the HTML structure after all results have loaded (or each time a file loads)
  2. Load the charts sequentially, by calling loadNdraw inside of jqJSON.done, meaning that chart B would only start loading after A is done—this is likely to be much slower.
  3. Populate the results in a temporary data structure, keep track of when all requests have completed, and then handle the DOM manipulation based on that data.

Option 3 seems to be your best bet in this situation:

function loadNdraw(title, id) {
 $("#containerCharts").html("");
 var date = $("#dateChart");
 return $.getJSON("charts/" + id + "/" + date.val() + ".json");
}
var options = [
 { title: 'A', id: 'a' },
 { title: 'B', id: 'b' },
 { title: 'C', id: 'c' },
 { title: 'D', id: 'd' }
];
for (var option of options) {
 option.promise = loadNdraw(option.title, option.id);
}
$.when(...options.map(o => o.promise)).done(function(...results) {
 results.forEach(function(dataArray, idx) {
 var title = options[idx].title;
 var id = options[idx].id;
 $("#containerCharts").append(
 "<div class='divStandard'>"
 + "<div class='titleChart'>"
 + "<div style='float: left;'>" + title + "</div>"
 + "<div style='float: right;'>" + dataArray[0].lastUpdate +"</div>"
 + "<div style='clear: both;'></div>"
 + "</div>"
 + "<center><div id='" + id + "' class='bodyChart'></div></center>"
 + "</div>"
 );
 });
});

Note a couple of things here:

  1. The argument to $.when is a listing of of Thenables—objects like your jqXHR with a then method. You can pass it an array objects by expanding it with the ...spread operator.
  2. The callback for $.when takes a listing of response objects as its parameter, in the order in which the requests were made. They can be collected into an array using the ...rest parameter syntax.
answered Dec 7, 2018 at 10:55

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.