JavaScript function not returning array [duplicate]

JavaScript function not returning array [duplicate]
javascript
Ethan Jackson

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: https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Async_JS/Promises

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);

Related Articles