get QueryTask results to return immediately within function

3084
3
Jump to solution
09-16-2016 02:44 PM
AndrewFarrar
Occasional Contributor

So I'm new to working with promises, but I'm having trouble wrapping my head around these asynchronous requests.  I am running a QueryTask within a result loop from a FindTask.  I am outputting all results to an array, to display once everything finishes up.  The issue I am experiencing comes with accessing the results.  I can pull out the results from the FindTask with no problem, but when I perform an "execute().then()" statement for my query task, those results are not returned until the promise resolves.  However, I would like to access those results sooner (e.g. as soon as that query task is executed).  My question is, is there any way to execute a QueryTask without using Promises?  Or is there a way to return results immediately within a promise?

My code is posted below for clarification.   the goal is to perform a spatial query based off of the returned result of a FindTask, without displaying a map.  Any help or tips are much appreciated!

<script>
    require([
      "esri/tasks/QueryTask",
      "esri/tasks/support/Query",
      "esri/tasks/FindTask",
      "esri/tasks/support/FindParameters",
      "dojo/_base/array",
      "dojo/dom",
      "dojo/on",
      "dojo/domReady!"
    ], function(QueryTask, Query, FindTask, FindParameters, arrayUtils, dom, on) {

      var loadingImg = dom.byId("loading");

      // Create a FindTask pointing to a map service
      var find = new FindTask({
        url: "http://gis2.co.frederick.va.us/arcgisweb/rest/services/FC_GIS/FCBase_TEST/MapServer"
      });

      // Set parameters to only query the point layer by name
      var params = new FindParameters({
        layerIds: [6],
        searchFields: ["ADDRESS"],
        returnGeometry: true
      });

      // Query task REST endpoint for polygon layer to be queried.
      var qt = new QueryTask({
        url: "http://gis2.co.frederick.va.us/arcgisweb/rest/services/FC_GIS/FCBase_TEST/MapServer/0"
      });

      resultsarray = [];

      // Executes on each button click
      function doFind() {
        // Display loading gif to provide the user feedback on search progress
        loadingImg.style.visibility = "visible";
        // Set the search text to the value of the input box
        params.searchText = dom.byId("inputAdr").value;
        // The execute() performs a LIKE SQL query based on the provided text value
        // showResults() is called once the promise returned here resolves
        // find.execute(params).then(showResults, rejectedPromise);

        find.execute(params)
          .then(doGeoQuery)
          .otherwise(rejectedPromise);
          debugger;
      }

      function doGeoQuery(response) {
        // "response.results" is the data object containing fields and geometry from the found feature
        var results = response.results;
        arrayUtils.forEach(results, function(findResult, i) {
          // Get each value of the desired attributes
          var geo = findResult.feature.geometry;
          var adr = findResult.feature.attributes.ADDRESS;
          var recnum = findResult.feature.attributes.RECNUM;
          resultsarray.push(adr);
          resultsarray.push(recnum);
          console.log("geo",geo);
          console.log("adr",adr);
          console.log("recnum",recnum);
          var spatialquery = new Query();
          spatialquery.outFields = ["PIN", "MLNAM"];
          spatialquery.geometry = geo;
          spatialquery.spatialRelationship = "intersects";
          // execute QueryTask 
          qt.execute(spatialquery).then(function(spatialresults) {
            console.log("spatialresults.features", spatialresults.features);
            resultsarray.push(spatialresults.features[0].attributes.MLNAM);
            resultsarray.push(spatialresults.features[0].attributes.PIN);
            console.log("resultsarrayloop",resultsarray);
          })
        });
        debugger;
        resultsTable.innerHTML = "";

        // If no results are returned from the task, notify the user
        if (resultsarray.length === 0) {
          resultsTable.innerHTML = "<i>No results found</i>";
          loadingImg.style.visibility = "hidden";
          return;
        }
        //console.log("resutls",results);

        // Set up row for descriptive headers to display results
        var topRow = resultsTable.insertRow(0);
        var cell1 = topRow.insertCell(0);
        var cell2 = topRow.insertCell(1);
        var cell3 = topRow.insertCell(2);
        var cell4 = topRow.insertCell(3);
        //var cell5 = topRow.insertCell(4);
        cell1.innerHTML = "<b>Address</b>";
        cell2.innerHTML = "<b>Recnum</b>";
        cell3.innerHTML = "<b>MLNAM</b>";
        cell4.innerHTML = "<b>PIN</b>";
        //cell5.innerHTML = "<b>geometry</b>";

        console.log("resultsarray",resultsarray);
        debugger;
        // Loop through each result in the response and add as a row in the table
        arrayUtils.forEach(results, function(findResult, i) {
          // Get each value of the desired attributes
          var adr = resultsarray[0];
          var recnum = resultsarray[1];
          var nam = resultsarray[2];
          var pin = resultsarray[3];

          // Add each resulting value to the table as a row
          var row = resultsTable.insertRow(i + 1);
          var cell1 = row.insertCell(0);
          var cell2 = row.insertCell(1);
          var cell3 = row.insertCell(2);
          var cell4 = row.insertCell(3);
          //var cell5 = row.insertCell(4);
          cell1.innerHTML = adr;
          cell2.innerHTML = recnum;
          cell3.innerHTML = nam;
          cell4.innerHTML = pin;
          //cell5.innerHTML = geo;
          debugger;
        });
      }

      var resultsTable = dom.byId("tblAdr");

      // Executes each time the promise from find.execute() is rejected.
      function rejectedPromise(err) {
        console.error("Promise didn't resolve: ", err.message);
        debugger;
      }

      // Run doFind() when button is clicked
      on(dom.byId("findBtn"), "click", doFind);
    });
  </script>

					
				
			
			
				
			
			
				
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Andrew,

     The queryTask returns a promise because it will take some time to make a roundtrip to the server. No you can not get the results right away. You have to develop your code to handle the promise delay. You can do this by placing your the result of your code in the deferred callback or use a dojo "All" to wait for all the deferreds in an array to return and execute the rest of your logic.

View solution in original post

3 Replies
RobertScheitlin__GISP
MVP Emeritus

Andrew,

     The queryTask returns a promise because it will take some time to make a roundtrip to the server. No you can not get the results right away. You have to develop your code to handle the promise delay. You can do this by placing your the result of your code in the deferred callback or use a dojo "All" to wait for all the deferreds in an array to return and execute the rest of your logic.

AndrewFarrar
Occasional Contributor

Good morning Robert, 

I was not aware of the dojo/promise/all function, but that looks like exactly what I need.  I knew that I wasn't formatting my code in the proper way to deal with promises somehow.  Thanks so much for your help!

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Glad to help point you in the right direction.

Don't forget to mark this question as answered by clicking on the "Correct Answer" link on the reply that answered your question.

0 Kudos