Search code examples
mysqlnode.jsdialogflow-esactions-on-google

Node callback returns mysql result but i cant print to the user with actions on google for dialogflow


I created an intent to get user information based on the ID he provides as param. Using a mysql module i can process the query and get the result. With a callback i can get the result to the main function but the agent ignores once i pass to a conv.ask(). What am i doing wrong?

This is my first script with node. I tried declaring pesquisar_aluno() in a variable so i could use in the main function but it retuns null.

const express = require('express');
const bodyParser = require('body-parser')
const mysql = require('mysql')
const {
  dialogflow,
  SignIn,
  SimpleResponse
} = require('actions-on-google')


app.intent('pesquisar.alunos', (conv, params) => {

  const aluno = params.aluno
  conv.ask('Vamos pesquisar')

  pesquisar_aluno(aluno,function(result){
    var resposta = result
    console.log(resposta) // returns the result
    conv.ask(resposta) // ignores it
  })

  console.log(resposta) // returns undefined
})


function pesquisar_aluno(aluno,callback)
{
  var connection = mysql.createConnection({
  host : process.env.MYSQL_HOST,
  user : process.env.MYSQL_USER,
  password : process.env.MYSQL_PASS,
  database : process.env.MYSQL_DB
  })
  connection.connect()

  var query = `SELECT * FROM aluno WHERE id_aluno = "${aluno}"`

  connection.query(query, function (error, results, fields) 
  {
    if(error) throw error

    var usuario = `RA =>${results[0].id_aluno} Nome => ${results[0].nome}`
    if(callback) return callback(usuario)
  })
}

Expect conv.ask(resposta) to print the result to the user but its not printing anything

Edit: Changed to promises. It worked!Thanks to Nick Felker and Prisoner

app.intent('pesquisar.alunos', (conv, params) => {

  const aluno = params.aluno
  conv.ask('Vamos pesquisar')

  let nome = pesquisar_aluno_promise(aluno).then(function(results) {
    return results[0].nome
  }).catch((err) => setImmediate(() => { throw err; }))

  return nome.then(function(result){
    conv.ask(result) 
  })
})

async function pesquisar_aluno_promise(aluno)
{
  return new Promise(function (resolve,reject) {
    var connection = mysql.createConnection({
    host : process.env.MYSQL_HOST,
    user : process.env.MYSQL_USER,
    password : process.env.MYSQL_PASS,
    database : process.env.MYSQL_DB
    })
    connection.connect()

    var query = `SELECT * FROM aluno WHERE id_aluno = "${aluno}"`
    connection.query(query, function (error, results, fields) 
    {
      if (error) {
        return reject(error)
      }
      resolve(results)
    })
  })
}

Solution

  • As Nick suggested in the comments, you need to use Promises when you are doing asynchronous operations.

    Additionally, however, you need to return that Promise from your Intent Handler so the Intent Dispatcher knows to wait for the result before continuing.

    In your case, this can just be adding return, so it might look something like this:

      return nome.then(function(result){
        console.log(result) //works
        conv.ask(result) //should work now
      })