1

I am creating a small domain availability checker. For that I will parse the desired domain into a form, and submit that to a PHP file with jQuery AJAX. However while I am looping through the different TLD's it suddenly gets undefined and I am not able to use the "TLD" for further processing within the loop. As far as I can read, it as something to do with the loop happening first and the requests made after, so I somehow have to freeze the index of my array. But I don't know how to do that.

This is my code:

$("input[name=submit]").click(function(){
        var getDomain = $("#domainsearch").val();
        var stripDomain = getDomain.split(".");
        var domain = stripDomain[0];
        var tlds = ["dk", "se", "com", "net"];
        for (var i = 0; i < tlds.length; i++ ) {
            var dataString = "domain=" + domain + "." + tlds[i];
            console.log(dataString);
            $.ajax({
                type: "POST",
                url: "search.php",
                data: dataString,
                success: function(data) {
                    console.log(domain + "." + tlds[i] + " is " + data);
                }
            });
        };
        return false;
    });

The printed console.log's looks like this: enter image description here

madsobel
  • 2,797
  • 3
  • 14
  • 22
  • AJAX + loop = need a closure. BRB searching a duplicate. – Karl-André Gagnon Jul 29 '14 at 20:45
  • You are using the asynchronous method `$.ajax(...)`, meaning that the loop continues to run independently of the ajax request, so the loop finishes, and `i` is no longer defined when you try to reference it for your `success` function. Like @Karl-AndréGagnon said above, you need to use a JS closure to preserve that variable. – Adam Jul 29 '14 at 20:46

3 Answers3

3

This is a classic JavaScript issue. In the success function (a closure), the i is being used. That callback runs in the future, once the AJAX call is done. By that point, the loop has finished, and i has been incremented to 4.

tlds[4] doesn't exist, and that's why you're getting undefined. The callbacks are all using the same i value.

To fix it, you need to create a new function to capture the value of i for each callback.

$("input[name=submit]").click(function(){
    var getDomain = $("#domainsearch").val();
    var stripDomain = getDomain.split(".");
    var domain = stripDomain[0];
    var tlds = ["dk", "se", "com", "net"];

    var createCallback = function(i){
        return function(data) {
            console.log(domain + "." + tlds[i] + " is " + data);
        };
    }

    for (var i = 0; i < tlds.length; i++ ) {
        var dataString = "domain=" + domain + "." + tlds[i];
        console.log(dataString);
        $.ajax({
            type: "POST",
            url: "search.php",
            data: dataString,
            success: createCallback(i)
        });
    };
    return false;
});
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
2

By the time the ajax calls return, the loop has long since ended, and i has run past the end of tlds. Trying to print tlds[i] is bound to fail.

Break the lookup into a separate function, with local variables that will be valid on the ajax callback:

var checkup = function(datastring, domain, tld) {
  $.ajax({
    type: "POST",
    url: "search.php",
    data: dataString,
    success: function(data) {
      console.log(domain + "." + tld + " is " + data);
    }
  });
};

for (var i = 0; i < tlds.length; i++ ) {
  var dataString = "domain=" + domain + "." + tlds[i];
  console.log(dataString);

  checkup(datastring, domain, tlds[i]);
};
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
0

You need to enclose the code in your loop in a closure as follows:

$("input[name=submit]").click(function(){
    var getDomain = $("#domainsearch").val();
    var stripDomain = getDomain.split(".");
    var domain = stripDomain[0];
    var tlds = ["dk", "se", "com", "net"];
    for (var i = 0; i < tlds.length; i++ ) {
        (function() {
            var dataString = "domain=" + domain + "." + tlds[i];
            console.log(dataString);
            $.ajax({
                type: "POST",
                url: "search.php",
                data: dataString,
                success: function(data) {
                    console.log(domain + "." + tlds[i] + " is " + data);
                }
            });
        })( i );
    }
    return false;
});
PeterKA
  • 24,158
  • 5
  • 26
  • 48