How to synchronise '.append()' and ajax query within 'for' loop
Due to ajax's asynchronism, all the 'success' calls are guaranteed to happen after all the <h3>
elements have been appended. Hence the symptom you describe.
This is simple to overcome by keeping a reference to the header element and inserting after it whatever is composed by showSubcategoryItems(data)
.
function showSingleCategory (subheader) { // keep reference to the appended <h3> var $header = $("<h3 class=\"subcat\">" + subheader.name + "</h3>").appendTo("#gallery"); $.ajax({ url: "http://localhost/mysite/wp-json/wp/v2/posts?categories=" + subheader.id + "", dataType: "json", contentType: "GET", success: function(data) { // Show items in subcategory after the corresponding header $(showSubcategoryItems(data)).insertAfter($header), } error: handleAjaxError });}if (subheaders.length > 0) { //If there are subcategories for (i = 0; i < subheaders.length; i++) { showSingleCategory(subheaders[i]); }}
And showSubcategoryItems()
will be of this general form :
function showSubcategoryItems(data) { var html = .....; // compose html from data return html;}
By appending the headers synchronously, their order is guaranteed to be congruous with the original subheaders
regardless of the order in which the ajax responses are received.
Try appending the <h3>
inside of your success callback. That way, it will append each header at the same time as its respective items, giving you the desired output.
function showSingleCategory (subheader) { $.ajax({ url: "http://localhost/mysite/wp-json/wp/v2/posts?categories=" + subheader.id + "", dataType: "json", contentType: "GET", success: function (data) { $("#gallery").append($("<h3 class=\"subcat\">" + subheader.name + "</h3>")); showSubcategoryItems(data); }, // Show items in subcategory error: handleAjaxError });}if (subheaders.length > 0) { //If there are subcategories for (i = 0; i < subheaders.length; i++) { showSingleCategory(subheaders[i]); }}