4

I'm building a chat bot, which takes a message from chat, and sends it to an api which generates a random gif based on the message.

The axios request/response works correctly, but I need it to store a URL value from the response as an external variable.

The variable/URL will then be sent in chat using another function. This function cant be run inside the axios request/then statement, and I cant seem to get the variable to update from inside either.

I'm a bit stuck on this, and have yet to find a method which will do what I need it to. Any advice is appreciated.

How do I return the response from an asynchronous call? doesn't address how I can get this externally, as again I can't run the message function from inside the then statement.

const sentence = context.activity.text.replace('!guggy ', '');

//theoretically this would hold the api response, but this wont update as intended
//var apiResponse;

//api call function
   function postRequest(x) {
    return axios.post('http://exampleurl.here.com/helpapi', {
        "sentence" : x,
        "lang": "ru"
    },{
        headers: {
            "Content-Type":"application/json",
            "apiKey":"example-key-2020202"
                        }
                });
        }

//initiates api call, then logs response or error
postRequest(sentence).then(function(response) {                  
                   console.log(response.data.animated[0].gif.original.url); //this works, returns URL

//attempting to store the same value as external variable doesnt work
apiResponse = response.data.animated[0].gif.original.url; //the variable remains blank when called later

}).catch (function (error) {
    console.log(error);
});


//this has to be run outside of axios/then statement, or it will not work.
//this should take the url passed from the response, and send it as a chat message                     
await context.sendActivity(apiResponse);

This doesnt actually return any errors, and runs on the server. It just doesn't return the variable when I need it - its blank. I'm assuming this means I'm just overlooking or misunderstanding something crucial.

Shawn R.
  • 161
  • 1
  • 3
  • 13
  • You can't synchronously work with a value that's retrieved asynchronously. You must call `.then` on the Promise to consume it (or use `await`), and then do everything that depends on it inside the `.then` – CertainPerformance Jun 22 '19 at 23:09
  • I'm not sure what you mean by the other question isn't a dupe--it's *precisely* the issue you're having. This is the nature of async programming. It even gives you multiple solutions, like await. What about that doesn't work for you? – Dave Newton Jun 22 '19 at 23:24

1 Answers1

1

The order of execution in the code snippet is:

  1. Call axios
  2. axios sends the message over the network.
  3. context.sendActivity() is called with a blank apiResponse.
  4. exampleurl.here.com returns an answer to axios.
  5. axios calls the "then" clause.
  6. apiResponse gets assigned.

you need to properly wait for the server to return an error, as follows:

const sentence = context.activity.text.replace('!guggy ', '');

async function postRequest(x) {
    return await axios.post('http://exampleurl.here.com/helpapi', {
            "sentence" : x,
            "lang": "ru"
            },{
                headers: {
                    "Content-Type":"application/json",
                    "apiKey":"example-key-2020202"
                }
            });
}

try {
    const response = await postRequest(sentence);
} catch (error) {
    console.log(error);
}

console.log(response.data.animated[0].gif.original.url);
apiResponse = response.data.animated[0].gif.original.url;
await context.sendActivity(apiResponse);
root
  • 5,528
  • 1
  • 7
  • 15