jtrdev
jtrdev

Reputation: 932

Bot has to restart to pass user input to request function

I have an api that Looks similiar to this inside my node.js Skype Bot

var SearchName = '',
TaxBillNu = ''
_rows = '10',
SearchDetail;

function getMobileData (Name, TaxBill, Rows) {
url = "http://example.com/api/search/OwnerName="+Name+"&TaxBill="+TaxBill+"&Rows="+Rows;
request({
    url: url,
    json: true
}, function (error, response, body) {
        if (!error && response.statusCode === 200) {
         SearchDetail = body; 
        }else{
            session.beginDialog('/');

            err = error;
          }
})
}

Once the user gets to REName I ask them to type in a search query and then it goes to a list of search results using the API

bot.dialog('/REName', [
    function (session) {
        builder.Prompts.text(session, "Type a search query..");
    },
    function (session, results) {
        if (results.response) {
            SearchName = results.response;
            getMobileData(SearchName, TaxBillNu, _rows)
            if(err){
            session.send(err);
            }
            session.beginDialog('/REList');
        }
    }
]);

My problem so far, is that even though I get my search results back ( on the second go around ) I get an error at first that a problem has occured, the Search Variable is saved but the function does not update the Body of the json request until after it has restarted. How do i ensure that I can run the function after bot.dialog('/REName', [ and get the updated SearchDetail = body the first time?

Edit: At this point it takes 3 restarts before the URL is complete with user inputs and passes me what I need.

Upvotes: 0

Views: 76

Answers (1)

nwxdev
nwxdev

Reputation: 4635

Use asynchronous programming techniques to organize your program control flow.

Since you need to wait for an operation to complete (REST API request), and then pass that data to the next step, you've got a perfect use case for async.waterfall() control flow pattern.

For example, using the Node.js module async, construct an async.waterfall inside your dialog handler like this:

var async = require('async');

bot.dialog('/REName', [
    function (session) {
        builder.Prompts.text(session, "Type a search query..");
    },
    function (session, results) {
        if (results.response) {
            SearchName = results.response;
            // do async stuff here
            async.waterfall([
                function(callback) {
                    // modify your getMobileData() method so it returns desired result
                    var mobileData = getMobileData(SearchName, TaxBillNu, _rows);
                    callback(null, mobileData);
                },
               function(mobileData, callback) {
                   // mobileData gets passed from the previous function
                   // then call session beginDialog
                   session.beginDialog('/REList');
                   callback(null);
               }
           ], function (err, result) {
               // handle errors here
               session.send(err);
           });

        }
    }
]);

Upvotes: 1

Related Questions