1

I am using Promise to execute my AJAX function, and am using `.then()' when calling the function to imply that anything in the .then() scope is executed once the AJAX function is executed. However, the .then() still executes before the AJAX function is fully done retrieving data from the server. I have been stuck on this for really long, and am unable to figure out what exactly is causing the issue. Is my code wrong? Below is my code. Any help will be deeply appreciated!

Calling the AJAX Function

userLayer = this.addUserLayerTreemail(
            $loadingContent,
            $loadingDiv,
            treeLayers,
            map,
            heritage_cluster_layer_view_18,
            flowering_cluster_layer_view_18,
            IMP_FIELDS,
            suggestion,
            userPlottedLayerView18Options,
            userLayer,
            $speciesError
          ).then( function(response){
            //this gets executed before the function retrieves all the data from the server - it should return true, but returns false
            console.log(map.hasLayer(userLayer), "check if layer exists")
            setSearchState(true);
            $mapSearch.blur();
          }).catch(function(err){
            console.log("error caught", err)
          });

Defining the AJAX Function

addUserLayerTreemail(
  $loadingContent,
  $loadingDiv,
  treeLayers,
  map,
  heritage_cluster_layer_view_18,
  flowering_cluster_layer_view_18,
  IMP_FIELDS,
  suggestion,
  userPlottedLayerView18Options,
  userLayer,
  $speciesError
) {

  // let checked = this.getCurrentFilter(),
  const featureType = 'USERTREE';

  let queryString = '';

  suggestion = suggestion.toLowerCase();

  let $selectedOptionSearch = $('.mapFilterBtns.is-active').data('value');
  let all_trees="";

  let searchText= $('#mapSearch').val();

  let configData = {"searchText": searchText, "searchType" : $selectedOptionSearch};

    console.log("config", configData)
    
    // this function is called in the resolve() function below 
    function retrieveTrees(response) {

    let conditionalVal = " or ";
          let treeID = "";

          for(let i=0; i<response.length; i++) {
            treeID = response[i]['MYTreeID']
            if(i==0) {
                all_trees = `${IMP_FIELDS.TREEMAIL_SEARCH} like '%${treeID}%'`;
            } else {
                all_trees += conditionalVal + `${IMP_FIELDS.TREEMAIL_SEARCH} like '%${treeID}%'`;
            }
          }

          console.log("all trees here",all_trees);

          queryString = all_trees + ` and Actual_Tree_Type like '%${featureType}%'`;

          let isSearch = true;

          let layerOptions = $.extend(
            {
              where: queryString
            },
            userPlottedLayerView18Options
          );

         
          layerOptions.url = mapLayers.userPlantedLayer;
    
          userLayer = L.esri.featureLayer(layerOptions);

          userLayer
            .query()
            .where(queryString)
            .run((err, featureCollection, response) => {

              if (featureCollection.features.length > 0) {

                removeClass($loadingDiv, 'show');
                //adding the userLayer to the map
                userLayer.addTo(map);
                //this returns true after the .then() chunk is executed in the call above
                console.log(map.hasLayer(userLayer), "checking in ajax")


            });
            console.log(map.hasLayer(userLayer), "checking in ajax ")

          return userLayer;
    }


    return new Promise(function(resolve, reject){

      $.ajax({
        url: "../apis/treemailSearch",
        method: 'GET',
        dataType: 'json',
        data : configData,
        contentType: 'application/json',
        success: response => {
          return resolve(retrieveTrees(response));

              },
              error : function(err){
                reject(err, "printing error here");
              }
      });

    })
}
Ian Bell
  • 533
  • 5
  • 18
  • You are resolving your Promise with `resolve(retrieveTrees(response))`. This is an async function. It performs an async operation `.query()`, but you are returning `userLayer` immediately, before the `.query()` completes. See https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call – Jeremy Thille Sep 17 '21 at 07:19
  • Besides, you are assigning to `userLayer` a function to which you are passing `userLayer` (normal?). The `response` you are getting when the Promise resolves is not a value, but an asynchronous function that returns something before it resolves. Inside the `then()` you are not even using this complicated response, but testing `userLayer` itself, the same variable you are assigning the whole thing to... There's not only one issue in this code. I don't even understand what's going on in there. Try to ditch `.then()` entirely and use `async/await` instead – Jeremy Thille Sep 17 '21 at 07:23
  • @JeremyThille how can I fix this in my code? If you could help me by altering the code, I would be really appreciative of it, because based on your comments, I do not exactly get how can I resolve it. – Ian Bell Sep 17 '21 at 07:27
  • To be honest, neither do I :/ It needs a serious refactoring, but I don't even understand its logic, so it's very hard to refactor – Jeremy Thille Sep 17 '21 at 07:27
  • You have several variables called `response`, several `userLayer` (unless it's the same one??) You define a function inside another function, but I believe the major issue is you return `userLayer` before `.query()` ends. You are not even returning the _result_ of the query, so, really I have no idea what's going on here ^^' – Jeremy Thille Sep 17 '21 at 07:31
  • Yes, the `userLayer` variable is same across, as you can see, I am passing it as a parameter too within the function. – Ian Bell Sep 17 '21 at 07:36
  • How can I return the `userLayer` after `query()` ends? – Ian Bell Sep 17 '21 at 07:37
  • Again, please check this : https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call. This is an extremely common question, asked several times a day – Jeremy Thille Sep 17 '21 at 07:38
  • sure, I will work off it then, thanks! :) – Ian Bell Sep 17 '21 at 09:03

0 Answers0