0

EDIT - This question has been marked as a duplicate of this question, but it is not. My question is not "how to get the response from an async function". My issue is that I am attempting to use one of the solutions explained in that question (using a callback), but I must have the wrong function in my callback and I cannot figure out which.

As a newcomer to both JS and Node, I'm trying to work through incorporating an API like Google Maps into a botkit bot. After reading a number of SO questions on callbacks and watching some videos, I'm starting to figure callbacks out, but in the case below the callback is still returning undefined and I can't figure out why. I've placed the Google Maps call in a callback function which I then call when the appropriate message is heard by the bot.

Given the mapIt function:

let mapIt = function(queryString) {
    const mapsApiKey = 'THE_API_KEY';
    const googleMapsClient = require('@google/maps').createClient({
    key: mapsApiKey
    });
    googleMapsClient.geocode({
    address: queryString
    }, function(err, response) {
        if (!err) {
            formattedAddress = response.json.results[0]['formatted_address'];
            //console.log(formattedAddress);
            return formattedAddress;
        } else {
            return 'Maps API Error';
        }
    });
};

And the calling function:

let getMapsResult = function(suppliedString, callback) {
    return callback(suppliedString);
};

It seems like I should be able to use the returned value of mapIt as follows:

controller.hears(
  ['\\b.*what is the formatted address of\s*([^\n\r?]*)'], ['direct_message', 'direct_mention', 'mention'],
  function (bot, message) { 

    let queryLocation = message.match[1];
    bot.say(message, getMapsResult(queryLocation, mapIt));

});

Can anyone help me understand why I'm still getting undefined with calls to mapIt?

EDIT - I've tried calling bot.say() inside the googleMapsClient.geocode() function, but nothing happens. HOWEVER, console.log does log the Google Maps response:

googleMapsClient.geocode({
address: queryString
}, function(err, response) {
    if (!err) {
        formattedAddress = response.json.results[0]['formatted_address'];
        console.log(formattedAddress);
        bot.say(message, formattedAddress);

    } else {
        return 'Maps API Error';
    }

});

calling getMapsResult...

controller.hears(
  ['\\b.*what time is it in\s*([^\n\r?]*)', '\\b.*what\'s the time in\s*([^\n\r?]*)'], ['direct_message', 'direct_mention', 'mention'],
  function (bot, message) { 

        let queryLocation = message.match[1];
        getMapsResult(queryLocation, mapIt);

});
Marcatectura
  • 1,721
  • 5
  • 30
  • 49
  • 1
    'mapIt' doesn't have a return value. The callback function for the googleMaps call is run asynchronously and `mapIt` will always return `undefined` – russpol Jan 13 '18 at 16:30
  • Thanks @russpol - I thought putting `mapIt` in a callback would address that? – Marcatectura Jan 13 '18 at 16:33
  • 1
    `getMapsResult` does not accomplish anything. You should either call `bot.say` within the `googleMapsClient` callback function, or make the call synchronous with `async/await` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function – russpol Jan 13 '18 at 16:51
  • @russpol I've added `bot.say()` to the googleMapsClient function (see edit at bottom), but it doesn't do anything when `mapIt` is called. However, a console.log I added to the same place does log the API response. – Marcatectura Jan 13 '18 at 18:27
  • this is probably because `bot` is not accessible within the scope of that function. I suggest checking out this question for a better understanding of async functions https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call which – russpol Jan 13 '18 at 19:06

0 Answers0