简体   繁体   中英

why am I getting undefined on this function?

I'm building a dialogflow agent that uses Airtable as database (library: airtable js)

Everything works fine except I can't get the value "out of" the function in order to send it back to the dialogflow agent.

Function

function showSinglePrice(agent) {
    var finalPrice;
    var arraySinglePrice = null;

    const item = agent.context.get("item"),
      place = item.parameters.place,
      size = item.parameters.size,
      type = item.parameters.type;

    base(tablePlaces)
      .select({
        maxRecords: 10,
        view: viewName,
        filterByFormula: `AND({type} = "${type}",{size} = "${size}",{place} = "${place}")` 
      })
      .firstPage(function(error, records) {
        if (error) {
          response.send({ error: error });
        } else {
          arraySinglePrice = records.map(record => {
            return {
              price: record.get("price")
            };
          });

          console.log(arraySinglePrice); //this works fine

          finalPrice = arraySinglePrice[0].price; //this works fine

          return finalPrice;
        }
      });   
   
    agent.add(`I wanted to get the result in here: ${finalPrice}`); //undefined
  }

I'm new to asynchronous programming, so I'm probably messing up with the Airtable js promises, but can't figure it out how to get it to work.

Would appreciate any help

EDIT

THANKS @PRISONER FOR THE HELP.

FOR THOSE IN NEED, HERE IS THE WORKING CODE:

function showSinglePrice(agent) {    

    const item = agent.context.get("item"),
      place = item.parameters.place,
      size = item.parameters.size,
      type = item.parameters.type;

    return base(tablePlaces) //defined variable before this function
      .select({
        maxRecords: 1, //just want 1
        view: viewName, //defined variable before this function
        filterByFormula: `AND({type} = "${type}",{size} = "${size}",{place} = "${place}")`
      })
      .firstPage()
      .then(result => {
        
        console.log(result);

        var getPrice = result[0].fields.price;

        agent.add(`the current price is: $ ${getPrice}`); //its working
      })
      .catch(error => {
        console.log(error);

        response.json({
          fulfillmentMessages: [
            {
              text: {
                text: ["We got the following error..."] //will work on it
              }
            }
          ]
        });
      });
  }

You're correct, there are some issues with how you're using Promises. You're using a callback function in your call to firstPage() instead of having it return a Promise. So you could have written that part to look something like this:

  .firstPage()
  .then( records => {
    // Work with the records here
  })
  .catch( err => {
    // Deal with the error
  });

Once you're dealing with Promises, everything you want to do must be done inside the .then() block. So you'll need to move the agent.add() in there.

You also need to return the Promise, so Dialogflow knows that theres an asynchronous operation taking place. Since the .then() and .catch() functions return a Promise, you can just return the result of the whole expression. So something like

  return base(tablePlaces)
      .select(query)
      .firstPage()
      .then(/*function*/)
      .catch(/*function*/);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM