5

Edit: I have since figured out the issue with the help of the other users that commented below. The issue is that using jQuery.load() has a lag time. And as pointed out below, the problem was the variable was seen, just not the data within it. My solution to the below problem was adjust the code slightly using jquery's deferred object functions.

$.ajax({
    url: 'koc-click-tracker-loader.php',
    data: {url: 'ar'},
    dataType: 'html',
    context: document.body })
.done( function( data ) {
    // Same functionality as below
    });

Original Post: I am trying to parse an HTML table with 7 columns

Rank | Username | Highest CPM | Last 24h | Total clicks | Links Left | Last Clicked

Then I'm trying to put each row's data into a JSON object. However, when I try to access the data outside of the .each() loop, I can not. My variable is defined in the global scope. When I try to, for debugging sake, alert(output1.Rank).

var output = [];
$(function(){
    var output = [];
    $("#_BLANK").load("koc-click-tracker-loader.php #ar_content table", { url: 'ar' }, function() {
        var data = $("#_BLANK table tbody"); i=0;
        data.find('tr').each( function() {
            var $td = $(this).find('td');

            if ( i > 0 ) { // Skip first iteration, has blank data.
            output[i] = {
                Rank: $td.eq(0).text(),
                User: $td.eq(1).text(),
                KocID: $td.eq(1).find('a').prop("href"),
                CPM: $td.eq(2).text(),
                Last24: $td.eq(3).text(),
                TotalClick: $td.eq(4).text(),
                LinksLeft: $td.eq(5).text(),
                LastClicked: $td.eq(6).text() };
                }
            i++;
            });
        // Will Error here as well.
        });
    alert(output[1].Rank); // Errors here.
    console.log("output", output); // Shows all the data properly.
    });

Cannot read property 'Rank' of undefined.

Again, for some reason, my variable isn't global. Or there is something I'm missing something with jQuery...

Tony Arnold
  • 649
  • 2
  • 7
  • 15
  • 1
    `alert(output[0].Rank);` gives an error because your `output[0]` element is `undefined` - you deliberately skip index 1 in your loop. – nnnnnn Aug 30 '16 at 05:20
  • In this case, that is correct. Typo on my part. 1 or more still error. – Tony Arnold Aug 30 '16 at 05:22
  • In that case it would seem to be a duplicate of [this question](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call?noredirect=1&lq=1) and quite a few others. Note that it isn't telling you that `output` is undefined, it is telling you that `output[1]` is undefined. – nnnnnn Aug 30 '16 at 05:23

1 Answers1

1

It's because your $.each() function is inside a $.load() function.

The load function is an async call. You are in a race condition.

I bet if you put a break point on the output[i] = { line, and also on the alert(output[0].Rank); line, you will hit the alert first.

  • 1
    It's not really a "race condition" in the sense of a situation where the timing of the outcome can't be determined in advance. We know the `.load()` callback will *definitely* run after the other code runs. – nnnnnn Aug 30 '16 at 05:24
  • yes, and he is trying to access an attribute on an object that doesn't exist yet, hence the error. – Paul Witschger Aug 30 '16 at 05:26
  • Whoa... There was a lot more to this issue then I realized. – Tony Arnold Aug 30 '16 at 05:30