user2549244
user2549244

Reputation: 3

Uninitialized variable when processing without alerts

I'm trying to build a log reader in Javascript/jQuery/PHP that displays the content of a text-file in an ingrid table.

The Javascript-part has the following functions:

<script type="text/javascript">
$(function() {
  // Count number of lines in the log file
  var $anzahlElemente=0;
  $.countLines = function() {
    $.get("../log.log", function(text) {
      var $lines = text.split(/\r|\r\n|\n/);
      $anzahlElemente = $lines.length-1;
    });
  };

  // Generate table
  $.showTable = function() {
    $("#table1").ingrid({
      url: 'ingrid.php',
      height: 625,
      initialLoad: true,
      rowClasses: ['grid-row-style1','grid-row-style1','grid-row-style2','grid-row-style1','grid-row-style1','grid-row-style3'],
      sorting: false,
      paging: true,
      totalRecords: $anzahlElemente
    });
  }

$.countLines();
$.showTable();
});
</script>

The problem now is that there seems to be a problem with the order or the sequence the functions process. After the two functions are done, the $anzahlElemente is still 0. $anzahlElemente is needed to display the tables paging function.

The weird thing is, when I try the following, the first alert shows "0" and the second one the correct number of lines. Without the alerts, the number of elements and the paging-function is missing. But with them, all works correctly, besides that I don't want to have these alerts. ;)

$.countLines();
alert($anzahlElemente);
alert($anzahlElemente);
$.showTable();

Do you need all other parts, like the html, php, css and images or do you see my mistake(s) directly?

EDIT: I hope it is allowed to attach files. I didn't find an upload option so I did it on this way: ingrid.zip

Upvotes: 0

Views: 121

Answers (2)

Rune FS
Rune FS

Reputation: 21742

The problem is a common misconception of how javascript code involving asyncronous I/O is executed. In your code showTable is actually executed before the named variable is set due to $.get being asyncronous

you could change your code to

var countLines = function(renderTable) {
    $.get("../log.log", function(text) {
      var $lines = text.split(/\r|\r\n|\n/);
      showTable($lines.length-1)
    });
};
// Generate table
var showTable = function(anzahlElemente) {
    $("#table1").ingrid({
      url: 'ingrid.php',
      height: 625,
      initialLoad: true,
      rowClasses: ['grid-row-style1',
                   'grid-row-style1',
                   'grid-row-style2',
                   'grid-row-style1',
                   'grid-row-style1',
                   'grid-row-style3'],
      sorting: false,
      paging: true,
      totalRecords: anzahlElemente
    });
}

$(function() {
  countLines(showTable);
});

in this manner the showTable will only execute when the $.get is successful.

In a little more details. The call to countLines actually ends before the call to $.get does and in your code your are then executing the call to showTable prior to the $.get calling executing the callback (the anonymous function setting $anzahlElemente. When you insert the alert you are changing the timing giving the call to said callback enough time to execute.

Upvotes: 2

eonj
eonj

Reputation: 119

Try $.countLines().end().showTable();.

Upvotes: 0

Related Questions