JavaScript function not returning array [duplicate]
![JavaScript function not returning array [duplicate]](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2F80wy3gkl%2Fproduction%2Fe6181cc418095a9f2e6e055e375b58562cbfb341-1280x720.png%3Fh%3D1000&w=3840&q=75)
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> </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:
- Return your promise from
requestDomains
:
return domainRequest.then(function(response){
- 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