I have a click event which displays details of an item from a JSON source, I also have another call for more JSON displaying related items, both within the same click event.
The problem is sometimes, not always I need two clicks for the second JSON call to display (related items). I’m wondering how I can insure/guarantee when the items display, both JSON results will be shown on first click.
Code
$(document).on('click', '.more', function(e){
....
var json_item = "//example.com/search.json?..";
var related_items = "//example.com/search.json?..";
// details
$.getJSON(json_item, function(data) {
$.extend(data, renderFuncs);
var templateB = $('#itemTemplate').html();
var htmlB = Mustache.render(templateB, data);
$('#item').html(htmlB);
});
// related
$.getJSON(related_items, function(data) {
$.extend(data, renderFuncs);
var templateX = $('#relatedTemplate').html();
var htmlX = Mustache.render(templateX, data);
$('#related').html(htmlX);
});
e.preventDefault();
});
Probably the easiest way is to chain both calls together with a then():
$(document).on('click', '.more', function(e){
....
var json_item = "//example.com/search.json?..";
var related_items = "//example.com/search.json?..";
// details
$.getJSON(json_item, function(data) {
$.extend(data, renderFuncs);
var templateB = $('#itemTemplate').html();
var htmlB = Mustache.render(templateB, data);
$('#item').html(htmlB);
}).then(
// related
$.getJSON(related_items, function(data) {
$.extend(data, renderFuncs);
var templateX = $('#relatedTemplate').html();
var htmlX = Mustache.render(templateX, data);
$('#related').html(htmlX);
});
);
e.preventDefault();
});
This will ensure they are carried out sequentially.
Or, as $.getJSON returns a Promise, you can use Promise.all to do something when the Promises resolve:
$(document).on('click', '.more', function(e){
....
var json_item = $.getJSON("//example.com/search.json?..");
var related_items = $.getJSON("//example.com/search.json?..");
Promise.all([json_item, related_items]).then(function(data){
// Both promises done!
// Do something with data
});
e.preventDefault();
});
var json_item = $.getJSON("//example.com/search.json?..");
var related_items = $.getJSON("//example.com/search.json?..");
With Promise.all, the requests will all get fired off at once, then when the final one resolves, the callback will execute. Using .then() the requests will fire one after another.
Well spotted, so we are generally just wrapping the promise all around the calls, if thats correct?
$(document).on('click', '.more', function(e){
....
var json_item = "//example.com/search.json?..";
var related_items = "//example.com/search.json?..";
Promise.all([json_item, related_items]).then(function(data){
$.getJSON(json_item, function(data) {
$.extend(data, renderFuncs);
var templateB = $('#itemTemplate').html();
var htmlB = Mustache.render(templateB, data);
$('#item').html(htmlB);
});
$.getJSON(related_items, function(data) {
$.extend(data, renderFuncs);
var templateX = $('#relatedTemplate').html();
var htmlX = Mustache.render(templateX, data);
$('#related').html(htmlX);
});
});
});
And is it possible to combine the two getJSON calls like you have done with the Promise.all ? $.getJSON(json_item, related_items, function(data) {}
So the benefit of using .then means we don’t have to wait for everything to be fully loaded. But if we use Promise.all nothing will show until everything is available. Is that right?
Cool, just seen your latest post thanks, taking shape
I’ll run some further testing lots of useful information, thanks.