0

I have an Alexa skill that takes the device's address and uses that information to find a nearby facility. According to this solution here, this is due to Javascript's asynchronicity.

The proposed solution in the above-linked question is to pull the http call into its own function with a callback. I have done that (see code below) but the http request is still not returning.

I have also taken a look at the solution here as proposed by @jfriend00. My callbacks are structured the same way. I still don't understand why my callbacks aren't returning before the rest of the code runs.

getKaiserBuildingHandler()

const getKaiserBuildingHandler = function() {
    console.info("Starting getKaiserBuildingHandler()");
    
    ...

      switch(addressResponse.statusCode) {
          case 200:
              console.log("Address successfully retrieved, now responding to user.");

              ...

              const nearestKPFacility = getKaiserBuildingHelper(buildingType, address);
              
              ...

              break;
          
          ...
      }

      console.info("Ending getKaiserBuildingHandler()");
    });

    ...
};

getKaiserBuildingHelper()

const getKaiserBuildingHelper = function(buildingType, address) {
  console.info("Starting getKaiserBuildingHelper()");

  // var facilityOutput = Messages.ERROR;
  var facilityOutput = "Inside building helper function, initial value.";

  if (buildingType == BLDG_TYPE.PHARMACY ||
      buildingType == BLDG_TYPE.CLINIC ||
      buildingType == BLDG_TYPE.HOSPITAL) {

    ...
    
    facilityOutput = "Before get JSON call.";

    getJSON(buildingType, function(err, data) {
      if (data != "ERROR") {
        console.info("Received data from callback: ", data);
        facilityOutput = "The closest Kaiser Permanente " + buildingType + " to your location is located at " + data + ".";
      } else {
        console.error("Error with data received from callback. ", err);
        facilityOutput = "Entered JSON call, returned ERROR.";
      }
    });
  }

  ...

  return facilityOutput;

  console.info("Ending getKaiserBuildingHelper()");
}

getJSON()

const getJSON = function(building, callback) {
  console.info("Starting getJSON()");

  Axios
    .get(getFacilitySearchEndpoint(building))
    .then(function(response) {
      callback(null, response);
    })
    .catch(function(error) {
      callback(error, "ERROR");
    });

  console.info("Ending getJSON()");
}

getFacilitySearchEndpoint() [wikipedia api just as placeholders]

const getFacilitySearchEndpoint = function(building) {
  console.info("Starting getFacilitySearchEndpoint()");

  switch (building) {
    case BLDG_TYPE.HOSPITAL:
      console.info("Ending getFacilitySearchEndpoint() with " + building);
      return "https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&utf8=1&srsearch=Albert+Einstein";
      break;
    case BLDG_TYPE.PHARMACY:
      console.info("Ending getFacilitySearchEndpoint() with " + building);
      return "https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&utf8=1&srsearch=Harry+Potter";
      break;
    case BLDG_TYPE.CLINIC:
      console.info("Ending getFacilitySearchEndpoint() with " + building);
      return "https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&utf8=1&srsearch=Tony+Stark";
      break;
    default:
      console.info("Ending getFacilitySearchEndpoint() with default");
      break;
  }
  console.info("Ending getFacilitySearchEndpoint()");
}
Mike
  • 1,307
  • 3
  • 17
  • 29
  • What is the expected result? Why do you call `console.info()` after `return` statement? – guest271314 Nov 08 '17 at 23:19
  • The expected result of this debugging is to see the contents of `result` in the `axiosHelper()` function. But if you're asking about the end goal, then that is the retrieve a physical address from `result`, which returns as the `data` parameter in the `getKaiserBuildingHelper()` function's callback to be added to the `facilityOutput` variable which is returned and emitted by Alexa. – Mike Nov 08 '17 at 23:24
  • Hope that makes sense. The `console.info()` call after the `return` statement is for debugging purposes. – Mike Nov 08 '17 at 23:25
  • `getKaiserBuildingHelper` attempts to return facilityOutput however it just initiates an async ajax request so facilityOutput will probably be undefined. – James Nov 08 '17 at 23:25
  • @James, you are correct. Except `facilityOutput` is not undefined, it is returning it's last assigned value which is "Before get JSON call." I set it to that for debugging purposes as well. – Mike Nov 08 '17 at 23:27
  • Why do you expect `console.info()` to be reached after `return` statement? Is `console.info(response)` not logged within function passed to `axiosHelper()`? What is text of `getFacilitySearchEndpoint`? – guest271314 Nov 08 '17 at 23:27
  • If you take a look at the screenshot of the console logs, you can see that `console.info("Ending getKaiserBuildingHelper()");` is being called just fine and both `console.info(response);` & `console.info("Ending axiosHelper()");` are not getting called. – Mike Nov 08 '17 at 23:28
  • You are trying to return the result of an asynchronous function call outside of the asynchronous function callback at `return facilityOutput` – guest271314 Nov 08 '17 at 23:47
  • @guest271314 yes, per the solution I linked in the original questions, I put the Axios call in its own separate asynchronous function. Even if I move it back to its original location inside of ‘getJSON()’, I will still get the same result. – Mike Nov 08 '17 at 23:50
  • Where is `BLDG_TYPE` defined? – guest271314 Nov 08 '17 at 23:53
  • @guest271314 in this file. I didn’t add it in the snippet because it is working as expected. – Mike Nov 09 '17 at 00:02
  • Note also that the response is served without `Access-Control-Allow-Origin` header `Failed to load https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&utf8=1&srsearch=Tony+Stark: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://stackoverflow.com' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.` – guest271314 Nov 09 '17 at 00:03
  • @guest271314 I’m sorry, I’m not familiar with those headers and what they do. Could you explain, please? Also, where are you seeing that information? – Mike Nov 09 '17 at 00:07
  • Both `getJSON()` and `getKaiserBuildingHelper()` are not properly handling async responses. See the answer yours has been marked a duplicate of for details on how to do that. – jfriend00 Nov 09 '17 at 00:08
  • https://stackoverflow.com/questions/10636611/how-does-access-control-allow-origin-header-work – guest271314 Nov 09 '17 at 00:09

0 Answers0