I have a query widget that queries a view table on ArcGIS REST. In the widget.js file, I am building a whereclause with the widget parameters and using QueryTask to query the database. I need to run two instances of QueryTask, the second takes a lot of time because it has to use statistical results from each row from the 1st query by looping through (67 times) to build an array of rows. [ [...], [...], [...] ]. I then need to format the results of the results array and create a layer. All of this works, except that I am having an async issue. I can't start processing the result array to create the layer until it is done populating. I am going to post a general outline of what I have now and what I have tried, but I won't post all of the code because it is hundreds of lines:
//build whereclause here
...building whereclause...
var queryTask = new QueryTask(tableUrl);
var buckQuery = new Query();
//statistical definitions here (not shown)
buckQuery.returnGeometry = false;
buckQuery.outFields = ["*"];
buckQuery.outStatistics = [statSum, statAvg, statMax, statCount];
buckQuery.orderByFields = ["COUNTY_NAME"];
buckQuery.where = whereclause;
queryTask.execute(buckQuery).then(function(response) {
var QueryResults = response.features;
let resultArr = [];
for((var i = 0; i < QueryResults.length; i++) {
let rowSum = null;
...more code
rowSum = [c, stats.FINALSCORESUM, stats.FINALSCOREAVG, stats.COUNTY_COUNT,
countArea, stats.MAXFINALSCORE];
var queryTask2 = new QueryTask(tableUrl);
var buckQuery2 = new Query();
buckQuery2.returnGeometry = false;
buckQuery2.outFields = ["COUNTY_NAME", "METHOD", "KillDate", "FULLNAME"];
buckQuery2.where = whereclause2 + " AND FINALSCORE = " + stats.MAXFINALSCORE
+ " AND COUNTY_NAME = '" + stats.COUNTY_NAME + "'";
queryTask.execute(buckQuery2).then(function(response) {
var QueryResults2 = response.features;
let stats2 = QueryResults2[0].attributes;
... more code
rowSum.push(stats2.METHOD.toString(), kd, stats2.FULLNAME);
resultArr.push(rowSum);
});
}
});
if(resultArr !== null || resultArr !== undefined) {
//here is where I need to do everything else
//resultArr is undefined
}
This produces an array as described above, but now I need to use that array to create new Formatted Results for the info window and result layer. All of this works fine (I set a timeout to 6 seconds for testing purposes!), I just can't figure out how to keep the javascript from running ahead, and wait on the result array to finish populating. I tried a few things:
First I tried using a Promise/resolve function like this:
//build whereclause here
...building whereclause...
var queryTask = new QueryTask(tableUrl);
var buckQuery = new Query();
//statistical definitions here (not shown)
buckQuery.returnGeometry = false;
buckQuery.outFields = ["*"];
buckQuery.outStatistics = [statSum, statAvg, statMax, statCount];
buckQuery.orderByFields = ["COUNTY_NAME"];
buckQuery.where = whereclause;
return new Promise(function(resolve, reject) {
queryTask.execute(buckQuery).then(function(response) {
var QueryResults = response.features;
let resultArr = [];
for((var i = 0; i < QueryResults.length; i++) {
let rowSum = null;
...more code
rowSum = [c, stats.FINALSCORESUM, stats.FINALSCOREAVG, stats.COUNTY_COUNT,
countArea, stats.MAXFINALSCORE];
var queryTask2 = new QueryTask(tableUrl);
var buckQuery2 = new Query();
buckQuery2.returnGeometry = false;
buckQuery2.outFields = ["COUNTY_NAME", "METHOD", "KillDate", "FULLNAME"];
buckQuery2.where = whereclause2 + " AND FINALSCORE = " + stats.MAXFINALSCORE
+ " AND COUNTY_NAME = '" + stats.COUNTY_NAME + "'";
queryTask.execute(buckQuery2).then(function(response) {
var QueryResults2 = response.features;
let stats2 = QueryResults2[0].attributes;
... more code
rowSum.push(stats2.METHOD.toString(), kd, stats2.FULLNAME);
resultArr.push(rowSum);
});
}
});
}).then(function(resultArr) {
showResults(resultArr);
});
function showResults(resultArr) {
...
}
but this didn't solve the issue. The showResults function executes without waiting and once again I get undefined for the result array. I also tried using a simple callback:
function getQueryResultsAndBuildArray (whereclause, callback)
//this is the same function as above so I won't paste it
...code goes here
callback(resultArr);
}
function showResults(resultArr) {
....
}
getQueryResultsAndBuildArray (whereclause, showResults);
Got the exact same result, undefined when executing the showResults function. Just looking for some input on what I am doing wrong and maybe a better way to approach.
Thanks!!
Solved! Go to Solution.
Franklin,
You need to use dojo/promise/all.
Robert,
Thanks, I am going to try that. I was able to get it working by getting a count of the results from the first query and then using a counter to count the loops, and when they matched, I executed the showResults function. I am going to try your way as well because it's probably the 'correct' method and I'm not sure it there are any pitfalls to the method I used.
Thanks!
hi,