1

I have got a weird jQuery issue that will most likely end up being something ridiculously minor, but after searching for a while I still can't get past it.

The issue
I have got a table with a list of domains. The table consists of two columns - domain name and IP address.

The IP address columns loads with the content of a loading icon, which is then supposed to be replace with the contents of an ajax call made.

The script is supposed to do a jQuery each() on a data attribute which is on the each IP column, take the data and perform a .get request which then returns that domains ip.

The problem When the .each runs, it checks the ip address and only replaces the final rowsloading icon.

Code

$("[data-domain]").each(function(){
        domain = $(this).data('domain');
        tr = $(this);

        $.get( "/database/ajax/domain/check", { domain: domain } )
          .done(function( data ) {
            tr.html(data);
          });
    });
Hunter
  • 414
  • 5
  • 15
  • 1
    you continue to change the tr and the call is async, so by the time any of the callbacks are done it's already changed to the last one – aw04 Apr 28 '17 at 13:55
  • 1
    The issue is to do with the scope of 'tr'. You can add a new scoped variable or you can re-find the row when the request has completed. Have a look here: http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – freedomn-m Apr 28 '17 at 13:59

1 Answers1

2

Think about the timing of what you're doing. You loop through some elements, and each time change a reference to the same tr variable to be the current element. You then make an async ajax call and register a callback. The loop continues to run and finish so naturally the value of tr is the last value.

Then your callbacks start firing, and they use the closed over value of the same variable (tr).

To achieve what you want, the obvious solution would be to create a new tr each time through the loop, which gets closed over inside your callback. To do this, simply declare it inside the loop (otherwise you're creating a global).

var tr = $(this)
aw04
  • 10,857
  • 10
  • 56
  • 89
  • Thank you. The lack of the `var` keyword on my `tr` variable was the cause of the problem. – Hunter Apr 28 '17 at 14:10
  • 1
    @LeonHunter In general, if you're going to omit the var (or const or let) be sure you understand what it's doing and have a good reason. I almost never declare a variable like that. – aw04 Apr 28 '17 at 14:13