tags:

views:

125

answers:

2

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);

      });

    }  
+1  A: 

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).

Nick Craver
thanks Nick.thanks for helping me write cleaner code =)
rob walsh
A: 

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');
}
redsquare