Search code examples
javascriptfirebasedialogflow-esactions-on-googledialogflow-es-fulfillment

How to use if else loop in Dialogflow for showing results


I have Javascript code for Dialogflow doing project on Google Actions. For this code if answer is in database means it will answer otherwise it is exiting out of app. So, I want to use else loop for this code plz help me

    function handleCompanyDetails(agent){   
  const RegNo = agent.parameters.RegNo;
  var ref8 =  admin.database().ref().child("Table/");
  var query8 = ref8.orderByChild("RegNo").equalTo(RegNo);
 return query8.once("value")
  .then(function(snapshot) {  
   snapshot.forEach(function(child) {

    if( !snapshot.exists() ){
      // There are no results, say so
      agent.add("There are no results for that account.");

    } else {
      // ... Do something with the data
         agent.add(`The student placed in  ` + child.val().CompanyName);
    }

  });

 });        
 }

Solution

  • While you can use a loop to show results, there are a few problems with how you've done to, and possibly even with what you're trying to return.

    First - Dialogflow requires you to return a Promise from any function that makes an asynchronous call, such as a call to the Firebase database. You're currently using the callback method. You should switch to using once() that returns a Promise instead, so that might look something like this:

    return query8.once("value")
      .then( snapshot => {
        // working with snapshot goes here
      })
      .catch( err => {
        console.error(err);
        agent.add("There was a problem.");
      });
    

    The second is how you work with snapshot itself. If you're expecting multiple results, you should be aware that you can only call agent.add() with a text message twice and one basic card. If you want multiple cards, you may want to use a list or carousel instead.

    If you are expecting only one response indexed off the RegNo, which it looks like you may be, then you should just include that as part of the path and get the value of the snapshot. You wouldn't need a loop in this case.

    Update based on updated code.

    As you noted, you're not sending anything if there are no results, so the Action exits with an error.

    The easiest way to do this is to use snapshot.exists() to check if there are any results in the snapshot. If there aren't any, then you can return an error. That might look something like

    return query8.once("value")
      .then(function(snapshot) {  
    
        if( !snapshot.exists() ){
          // There are no results, say so
          agent.add("There are no results for that account.");
    
        } else {
          // ... Do something with the data
        }
    
      });
      // ...
    

    If you do have results, you still have the issue that you may be sending back too many replies. You can only have one agent.add() with a message to be spoken (or two, at the most, but don't do that) and only one Card, unless you use a List or Carousel. So it would be better for you to build that message inside the loop.