Tutorial :Loading JSON into table, sometimes table loads w/o data



Question:

So, I have an application where I have a blank table in the DOM and I load JSON table into the table dynamically with jQuery's .getJSON function. This works...most of the time.

Sometimes my table appears on the page without any data, although firebug says my table and the JSON where loaded.

Anyone have any ideas why this may happen?

Is it possible that the JSON is loading before the table (it shouldn't be)?

Would a setTimeout be helpful, to make sure the table is loaded before I try loading the JSON?

Code:

if (currentProdSelectValue === "Candy" && currentAppSelectValue === "Candy Store") {   $('#page_content').children().fadeOut('slow');    $('#page_content').load('page_eleven_new.html').hide().fadeIn('slow');     $.getJSON('js/page_eleven.js',      function(data){              $('table#table_first_row tr:first td:first').html(data.candy.dataDaily.timeScope);            $('table#table_first_row tr:first td:nth-child(2)').html(data.candy.dataDaily.lemonHmarsBarss);            $('table#table_first_row tr:first td:nth-child(3)').html(data.candy.dataDaily.snickers);            $('table#table_first_row tr:first td:nth-child(4)').html(data.candy.dataDaily.cottonCandy);            $('table#table_first_row tr:first td:nth-child(5)').html(data.candy.dataDaily.marsBars);            $('table#table_first_row tr:first td:nth-child(6)').html(data.candy.dataDaily.babyRuth);            $('table#table_first_row tr:first td:nth-child(7)').html(data.candy.dataDaily.nerds);            $('table#table_first_row tr:first td:nth-child(8)').html(data.candy.dataDaily.atomicFireBalls);            $('table#table_first_row tr:first td:nth-child(9)').html(data.candy.dataDaily.fruitStripeGum);                $('table#table_first_row tr:nth-child(2) td:first').html(data.candy.dataMonthToDate.timeScope);            $('table#table_first_row tr:nth-child(2) td:nth-child(2)').html(data.candy.dataMonthToDate.lemonHmarsBarss);            $('table#table_first_row tr:nth-child(2) td:nth-child(3)').html(data.candy.dataMonthToDate.snickers);            $('table#table_first_row tr:nth-child(2) td:nth-child(4)').html(data.candy.dataMonthToDate.cottonCandy);            $('table#table_first_row tr:nth-child(2) td:nth-child(5)').html(data.candy.dataMonthToDate.marsBars);            $('table#table_first_row tr:nth-child(2) td:nth-child(6)').html(data.candy.dataMonthToDate.babyRuth);            $('table#table_first_row tr:nth-child(2) td:nth-child(7)').html(data.candy.dataMonthToDate.nerds);            $('table#table_first_row tr:nth-child(2) td:nth-child(8)').html(data.candy.dataMonthToDate.atomicFireBalls);            $('table#table_first_row tr:nth-child(2) td:nth-child(9)').html(data.candy.dataMonthToDate.fruitStripeGum);              //table row three              $('table#table_first_row tr:last td:first').html(data.candy.dataYearToDate.timeScope);            $('table#table_first_row tr:last td:nth-child(2)').html(data.candy.dataYearToDate.lemonHmarsBarss);            $('table#table_first_row tr:last td:nth-child(3)').html(data.candy.dataYearToDate.snickers);            $('table#table_first_row tr:last td:nth-child(4)').html(data.candy.dataYearToDate.cottonCandy);            $('table#table_first_row tr:last td:nth-child(5)').html(data.candy.dataYearToDate.marsBars);            $('table#table_first_row tr:last td:nth-child(6)').html(data.candy.dataYearToDate.babyRuth);            $('table#table_first_row tr:last td:nth-child(7)').html(data.candy.dataYearToDate.nerds);            $('table#table_first_row tr:last td:nth-child(8)').html(data.candy.dataYearToDate.atomicFireBalls);            $('table#table_first_row tr:last td:nth-child(9)').html(data.candy.dataYearToDate.fruitStripeGum);          });        }    


Solution:1

Try this approach instead, loading the JSON after the table is in place...also I cleaned up the overall structure a bit:

if (currentProdSelectValue === "Candy" && currentAppSelectValue === "Candy Store") {    $('#page_content').children().fadeOut('slow');     $('#page_content').load('page_eleven_new.html', function() {      $.getJSON('js/page_eleven.js', function(data){          var cat = ['dataDaily', 'dataMonthToDate', 'dataYearToDate'];          var fields = ['timeScope', 'lemonHmarsBarss', 'snickers',                         'cottonCandy', 'marsBars', 'babyRuth', 'nerds',                         'atomicFireBalls', 'fruitStripeGum'];            for(var c = 0; i < cat.length; c++) {            $('table#table_first_row tr').eq(c).children().each(function(j, td) {              $(this).html(data.candy[cat[i]][fields[j]]);            });          }      });    }).hide().fadeIn('slow');  }  

This approach loops though the properties, in JavaScript data.candy.dataDaily.timeScope can be written as data.candy['dataDaily']['timeScope'], which you can use to your advantage here, specifying these names once and just looping through those properties...as you can see above, this saves just a bit of code ;)

The important part is the $.getJSON() is running as a callback to .load(), ensuring the table is there and these selectors are finding something to populate...which isn't the case currently. You're seeing an empty table now because they're loading out of order sometimes...this prevents that.

Alternatively, you could still load both, set data to a global variable, and use the .ajaxStop() event, and do the table population there (it will run after both complete).


Solution:2

Nick got in before me, however to prove my point regarding caching selectors I would alter his code only slightly

if (currentProdSelectValue === "Candy" && currentAppSelectValue === "Candy Store") {    $('#page_content').children().fadeOut('slow');     $('#page_content').load('page_eleven_new.html', function() {      $.getJSON('js/page_eleven.js', function(data){          var cat = ['dataDaily', 'dataMonthToDate', 'dataYearToDate'];          var fields = ['timeScope', 'lemonHmarsBarss', 'snickers',                         'cottonCandy', 'marsBars', 'babyRuth', 'nerds',                         'atomicFireBalls', 'fruitStripeGum'];            //cache tables rows          var $trs = $('#table_first_row tr');            for(var c = 0; i < cat.length; c++) {            $trs.eq(c).children().each(function(j, td) {              $(this).html(data.candy[cat[i]][fields[j]]);            });          }      });    }).hide().fadeIn('slow');  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »