I'm Joe Too
I'm Joe Too

Reputation: 5840

Export function with promise, wait for response

I'm calling a function inside a then statement, and that function has to wait for an event to fire, but my initial function is returning undefined almost immediately:

// call.js
const dialogflow = require('./dialogflow')
module.exports = {
  receive: functions.https.onRequest((request, response) => {
    ...
    let respondToUser = getUserId
      .then((uid) => {
        payload.uid = uid
        dialogflow.handleIncoming(payload).then((result) => {
          console.log(result)
        })
      })
      .then((result) => {
        console.log(result)
        response.end()
      })
    ...
  }
}

// dialogflow.js
module.exports = {
  handleIncoming: (payload) => {
    ...
    let df = dialogflow.textRequest(message.message, {
      sessionId: payload.from
    })
    .on('response', (response) => {
      return response.result.fulfillment.speech
    })
    .on('error', (error) => {
      return 'That\'s an error on my end. Try again later!'
    })
    .end()
  }
}

The goal is to call dialogflow.handleIncoming(payload) from call.js, wait for it to return some text, and then continue. But no matter how I have structured it, receive just keeps blowing through it and dialogflow.handleIncoming(payload) ends up undefined.

I've tried using a promise on df with no success, and I can't figure out how to make respondToUser wait for a full response from handleIncoming. Everything else is working so I'm only including relevant code.

This is using api.ai (dialogflow), but in cloud functions in Firebase if that helps. Appreciate any help!

Upvotes: 0

Views: 1389

Answers (2)

Nisan Coşkun
Nisan Coşkun

Reputation: 561

Problem is dialogflow.handleIncoming(payload) is not structured for async. Try this:

// dialogflow.js
exports.handleIncoming = (payload) =>
  new Promise((resolve, reject) => {
    ...
    let df = dialogflow.textRequest(message.message, {
      sessionId: payload.from
    })
    .on('response', (response) => {
      resolve(response.result.fulfillment.speech)
    })
    .on('error', (error) => {
      reject ('That\'s an error on my end. Try again later!')
    })
    .end()
  }

Upvotes: 1

TheF1rstPancake
TheF1rstPancake

Reputation: 2378

Your receive function isn't waiting for dialogflow.handleIncoming(payload) to complete. The then function that contains it doesn't have a return statement, so it's returning undefined rather than returning the result of dialogflow.handleIncoming (which is what you want).

let respondToUser = getUserId
      .then((uid) => {
        payload.uid = uid
        return dialogflow.handleIncoming(payload)
      })
      .then((result) => {
        console.log(result)
        response.end()
      })

The next then statement will contain the response from diagflow.handleIncoming.

Upvotes: 0

Related Questions