JavaScript function not returning array [duplicate]

JavaScript function not returning array [duplicate]

I have an ESRI 3.46 JavaScript application. There are a couple of functions which return data from an API. I am looping through the results and creating an array to be returned to other areas of my application. The problem I am having is the function is returning "undefined" instead of the array. If I send the results to the console before the return statement, the data is there. I am also using a little PHP in this.

        function requestDomains(layer){
          var dUrl = '<?php echo $emapFS; ?>/queryDomains';
          var domainRequest = new Request({
            "url" : dUrl,
            "content": {
              "f": "json",
              "layers": '['+layer+']',
            },
            async: false
          });
          //domainRequest.then(domainParse, requestFailed);
          domainRequest.then(function(response){
            var domains = response.domains
            var arr = [];
            //console.log(domains);
            jQuery.each(domains, function(key, value){
              var dname = value.name;
              arr[dname] = [];
              var cValues = value.codedValues;
              jQuery.each(cValues, function(k, v){
                var dcode = v.code.toString();
                var dvalue = v.name.toString();
                arr[dname][dcode] = dvalue;
              });
            });
            console.log(arr);  //<------------ This returns the array in console. Looks good
            return arr;

          });
        }

        function MainTabContent (results){
          var template = "";
          var wfeatures = results.features[0];
          //console.log("Main");
          var MainArray = <?php echo $mainFields; ?>;
          var layerid = mapLayers['Main Lines'];
          //console.log(layerid);
          var cDomains = requestDomains(layerid);
          console.log(cDomains); // <-----------------------This returns undefined
          template = "<i>Total features returned: " + wfeatures.length + "</i>";
          template += "<table border='1' style='width:1000px;'>";
          template += "<tr>"
          jQuery.each(MainArray, function(tkey, tvalue){
            template += "<th>"+tvalue+"</th>"
          });
          //template += "<th>Data</th>"
          template += "</tr>";
          for (var i = 0, il = wfeatures.length; i < il; i++)
          {
            template += "<tr>";
            jQuery.each(MainArray, function(key, value){

                switch(key)
                {
                  case "<?php echo $switchFields[4]; ?>":
                    template += '<td width="300">'+ wfeatures[i].attributes[key] +'</td>';
                  break;
                  case "<?php echo $switchFields[3]; ?>":
                    template += '<td width="100">'+ wfeatures[i].attributes['DIAMETER'] +' '+ wfeatures[i].attributes['MATERIAL'] + '<a href="#" onclick="showFeature(mainResults.features[0]['+ i +']); return false;">(show)</a></td>';
                  break;
                  case "<?php echo $switchFields[5]; ?>":
                    asbuilt = wfeatures[i].attributes[key];
                    //console.log(asbuilt);
                    if(asbuilt != 'Null')
                    {
                      template += '<td><a href="<?php echo base_url(); ?>gis/ab/' + asbuilt + '" target="_blank">' + asbuilt + '</a></td>';
                    } else {
                      template += '<td>&nbsp;</td>';
                    }
                  break;
                  case "<?php echo $switchFields[0]; ?>":
                    unitid = wfeatures[i].attributes[key];
                    template += "<td>"+ wfeatures[i].attributes[key] +"</td>";
                  break;
                  case "<?php echo $switchFields[1]; ?>":
                    unitid2 = wfeatures[i].attributes[key];
                    template += "<td>"+ wfeatures[i].attributes[key] +"</td>";
                  break;
                  case "<?php echo $switchFields[6]; ?>":
                    facilityID = wfeatures[i].attributes[key];
                    template += '<td><div class="csspointer" style="color:blue;text-decoration:underline;" onClick="window.open(\'/gis/HansenQuery/'+facilityID+'/COMPWMN\', \'\',  \'width=400,height=400,menubar=no,scrollbars=yes\')">Asset Data</div></td>';
                  break;
                  case "<?php echo $switchFields[7]; ?>":
                    mLength = parseFloat(wfeatures[i].attributes[key]);
                    template += "<td>"+ Math.round(mLength) +"</td>";
                  break;
                  default:
                  template += "<td>"+ wfeatures[i].attributes[key] +"</td>";
                }

            });
            //template += '<td><div class="csspointer" style="color:blue;text-decoration:underline;" onClick="window.open(\'/gis/HansenQuery/'+unitid+'/COMPWMN/'+unitid2+'\', \'\',  \'width=400,height=400,menubar=no,scrollbars=yes\')">Hansen</div></td>';
            template += "</tr>";
          }
          template += "</table>";

          return template;
        }

The above code was shortened a bit. I initially had the request for the data in one function and the parsing of the data into an array in another.

Answer

Seems you are in process of learning promises/async JS, please learn more: Read more

To fix your problem you should:

  1. Return your promise from requestDomains:
return domainRequest.then(function(response){
  1. Wait for the returned value:
requestDomains(layerid).then(cDomains =>{

// do the rest here
});

Also I would recommend using async/await even with legacy code, that would potentially limit number of bugs associated with then() nested callback hell and problems like yours, improves readability greatly:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

async function MainTabContent (results){

  ...

  var cDomains = await requestDomains(layerid);

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles