0

I have an function inside it i am using $.each method. I want to call another function alertMsg() after $.each completely executed. But when i use breakpoints i can see that before finishing the $.each method it executes the alertMsg function. why? how to solve it.

   function test(hospitalJson,blockJson){

    $.each(hospitalJson.organisationUnits, function (i, curr_hos) {

        if (curr_hos.id == orgUnit.id) {
            var stringPath=[];
            stringPath= curr_hos.path.split("/");
            outerloop:
                    for(var i=0;i<stringPath.length;i++){
                        for(var j=0;j<blockJson.length;j++){
                            if(stringPath[i]==blockJson[j].id){
                                document.getElementById('blockID').innerHTML = blockJson[j].id;
                                break outerloop;
                            }
                        }

                    }

            // to get district name
            var districtNameURL="../api/organisationUnits.json?fields=name&filter=id:in:[" + curr_hos.path.split("/")[4] + "]" ;

            $.get(districtNameURL,function(district){
                districtName=district.organisationUnits[0].name;
                console.log(districtName);
                document.getElementById('districtID').innerHTML = districtName;
            });

            alertMsg = 1;
            return false;
        }


    });
    //this message execute before finishing $.each
    alert(alertMsg);
}
  • 1
    `$.get` is an async call and because of that your alert gets triggered before finishing `$.each`. – Nikhil Aggarwal Jan 02 '16 at 11:19
  • 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) – Teemu Jan 02 '16 at 11:23
  • 2
    It isn't fired before the each loop finished BUT before async requests has completed. To avoid that, you can put all your requests in an array and apply deferred `$.when()` method on it, using relevant callback to set any following logic: http://stackoverflow.com/questions/5627284/pass-in-an-array-of-deferreds-to-when – A. Wolff Jan 02 '16 at 11:23

2 Answers2

1

Due to the fact that $.each has multiple AJAX calls inside, you need to create an array containing Promise objects that need to be resolved . Since you may not know the exact size of the parsed JSON object and jQuery $.when cannot handle arrays you need to extend it's functionality.

function test(hospitalJson, blockJson) {
  var deferreds = [];

  $.each(hospitalJson.organisationUnits, function(i, curr_hos) {

      //...
      deferreds.push(
        $.get(districtNameURL, function(district) {
          districtName = district.organisationUnits[0].name;
          console.log(districtName);
          document.getElementById('districtID').innerHTML = districtName;
        }));
    }
    return deferreds;

  });
}


var resolveData = test(hospitalJson, blockJson);
$.when.apply(null, resolveData).done(function() {
  alert(alertMsg);
});

JSfiddle demo

vorillaz
  • 6,098
  • 2
  • 30
  • 46
0

Change:

        $.get(districtNameURL,function(district){
            districtName=district.organisationUnits[0].name;
            console.log(districtName);
            document.getElementById('districtID').innerHTML = districtName;
        });

To:

        $.ajax({
            url: districtNameURL,
            type: "GET",
            async: false
        })
        .success(function (district) {
            districtName = district.organisationUnits[0].name;
            console.log(districtName);
            document.getElementById('districtID').innerHTML = districtName;
        });

This will stop the get action being asynchronous and therefore your logic will be processed in the expected order.

Steve Harris
  • 5,014
  • 1
  • 10
  • 25