0

I use the following function as onclick event on an ahref link:

function checkOrgSaved() {
   var orgName = $.trim($("#orgName").val());
   var orgNames = new Array();

    $.getJSON("organizations?action=getOrganizations&onlyName=true&CSRFToken=" + csrf_token,   function (result) {
        for (var i = 0; i < Object.keys(result.Orgs).length; i++) {
            var org = result.Orgs[i].name;
            orgNames.push(org);
        }
    });

    if ($.inArray(orgName, orgNames) == -1 || orgName == 0){
        alert("Foobar.");
        $("#editLink").attr("href", "javascript:void(0);");
    }
}

Like this, the orgNames array in the if statement is always empty. Why?

However if I declare the orgNames array inside the getJSON call and put the if statement also inside the getJSON() call, the array is filled correctly, but the line $("#editLink").attr("href", "javascript:void(0);"); does not work and a redirect is performed with a click on the ahref element.

What I'm trying to achieve is: If the orgName is empty or NOT in the orgNames array an JS alert should be thrown - without an redirect on the other page.

jwi
  • 1,116
  • 1
  • 18
  • 38
  • JS does not wait for async functions to finish, it will skip to your if block. Move your if block inside the getJSON below your for loop. – Mike Scotty Jun 28 '16 at 13:30
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – kemicofa ghost Jun 28 '16 at 13:31

4 Answers4

1

This is because the $.getJSON call is asynchronous, meaning the if statement will be executed before the JSON data is received and the callback is executed and orgNames is populated.

You might want to fetch the JSON and populate the array before the click occurs, and then just check agains the values:

var orgNames = new Array();

$.getJSON("organizations?action=getOrganizations&onlyName=true&CSRFToken=" + csrf_token,   function (result) {
  for (var i = 0; i < Object.keys(result.Orgs).length; i++) {
    var org = result.Orgs[i].name;
    orgNames.push(org);
  }
});

function checkOrgSaved() {
  var orgName = $.trim($("#orgName").val());

  if ($.inArray(orgName, orgNames) == -1 || orgName == 0){
    alert("Foobar.");
    $("#editLink").attr("href", "javascript:void(0);");
  }
}

This would also help avoid additional requests for the same JSON data.

Peteris Bikis
  • 221
  • 1
  • 5
0

Try changing your code to this:

    function checkOrgSaved() {
       var orgName = $.trim($("#orgName").val());
       var orgNames = new Array();
       $.getJSON("organizations?action=getOrganizations&onlyName=true&CSRFToken=" + csrf_token,   function (result) {
            for (var i = 0; i < Object.keys(result.Orgs).length; i++) {
                var org = result.Orgs[i].name;
                orgNames.push(org);
            }
            if ($.inArray(orgName, orgNames) == -1 || orgName == 0){
              alert("Foobar.");
              $("#editLink").attr("href", "javascript:void(0);");
        }
        });   
    }
Roxoradev
  • 863
  • 4
  • 13
0

The function you pass into $.getJSON as second parameter is a callback that will be executed after the asynchronous HTTP call has been completed.

The code after the $.getJSON is executed immediately, which means that the callback has most likely not run yet when you try to access the results via the array.

You have to move the logic that updates your UI into the callback function to ensure that the HTTP call has been completed when it is executed.

function checkOrgSaved() {
   var orgName = $.trim($("#orgName").val());
   var orgNames = new Array();

    $.getJSON("organizations?action=getOrganizations&onlyName=true&CSRFToken=" + csrf_token,   function (result) {
        for (var i = 0; i < Object.keys(result.Orgs).length; i++) {
            var org = result.Orgs[i].name;
            orgNames.push(org);
        }

        if ($.inArray(orgName, orgNames) == -1 || orgName == 0){
            alert("Foobar.");
            $("#editLink").attr("href", "javascript:void(0);");
        }
    });
}

For more info, have a look at jQuery's docs.

TimoStaudinger
  • 41,396
  • 16
  • 88
  • 94
  • Now my problem is like I mentioned above, the line `$("#editLink").attr("href", "javascript:void(0);");` does not work anymore. A redirect is performed after a click on the ahref element. – jwi Jun 28 '16 at 13:46
  • `$("#editLink").attr("href", "#") ` couldn't you do something like this? – Roxoradev Jun 28 '16 at 13:49
0

Javascript is an asynchronous language, right? What's happening is that your if statement runs before your get function's callback returns the result.

You should move your if check into the callback like this:

$.getJSON("organizations?action=getOrganizations&onlyName=true&CSRFToken=" + csrf_token, function(result) {
    for (var i = 0; i < Object.keys(result.Orgs).length; i++) {
        var org = result.Orgs[i].name;
        orgNames.push(org);
    }
    if ($.inArray(orgName, orgNames) == -1 || orgName == 0) {
        alert("Foobar.");
        $("#editLink").attr("href", "javascript:void(0);");
    }
});
Jeremy Jackson
  • 2,247
  • 15
  • 24