0

I don't think this is duplicate question since this does not concern jquery.

I am trying to build a chatbot that returns artist info when queried by our user. I am using Promise to wait for DB accessing then process the result to send back to user. However, the code continues regardless of our promise object.

We get the input from a user which then WATSON categorize it as a 'ask' type conversation. Then, we use the Promise object to access the DB and store the data from there and print it back to the user. Any thoughts on how to make our code actually stop until finish accessing the DB?

let getConversationResponse = (message, context) => {
    console.log("getConversationResponse in")
  let payload = {
    workspace_id: process.env.WORKSPACE_ID,
    context: context || {},
    input: message || {}
  };
    console.log("getConversationResponse : declare")
    payload = preProcess(payload);
    console.log("getConversationResponse : return promise")

return new Promise((resolved, rejected) => {
    // Send the input to the conversation service
    conversation.message(payload, function(err, data) {
        if (err) {
            rejected(err);
        }
        else {
            console.log("Check"+data.context.type);
            if(data.context.type == 'ask'){
                let artist = "Jan Tarasin";
                var iniPromise = artpromise(artist);
                iniPromise.then(function(result) {
                    console.log(result);
                    console.log(data.output.text);
                });
            }

            let processed = postProcess(data);
            ///////////////////////////////////////////////////

            ///////////////////////////////////////////////////
            console.log("getConversationResponse : return promise : postProcess done");
            if (processed) {
                //  if return value is the promise object,
                if (typeof processed.then === 'function') {
                    processed.then(data => {
                        resolved(data);
                    }).catch(err => {
                        rejected(err);
                    })
                }
                // if return value is the changed data
                else {

                    resolved(processed);
                }
            }
            else {
                // if there is no return data
                resolved(data);
            }
        }
    });
})

}

The artpromise function is below:

function artpromise (artist) {
    return new Promise(function(resolve, reject) {
        const MongoClient = require("mongodb").MongoClient;
        const url = 'mongodb://localhost:27017/mydb';
        MongoClient.connect(url, function(err, db) {
            if (err) throw err;
            var dbo = db.db("mydb");
            var query = {name: artist};
            artistinfo = dbo.collection("artistdb").find(query)
                .toArray(function(err, result) {
                    if (err) throw reject(err);
                    resolve(result);
                });
            db.close();
        })
    });
};
Maeror
  • 93
  • 2
  • 11
  • 2
    Promises do not make asynchronous code synchronous ... an all too common mistake. Not sure why so many people think that promises can do such impossible majick – Jaromanda X Mar 30 '18 at 08:03
  • @JaromandaX Then what do you suggest I use? – Maeror Mar 30 '18 at 08:05
  • @Maeror `async/await` or return all promises to build a chain. – Sven Mar 30 '18 at 08:06
  • 1
    Promises are fine, just understand how to use them ... which part of your code is "not waiting" for you? the `iniPromise.then` part? – Jaromanda X Mar 30 '18 at 08:06
  • @Svenskunganka - `async/await` will not help if one doesn't understand how promises work - one has to know how to walk before one can run – Jaromanda X Mar 30 '18 at 08:07
  • @Svenskunganka - I take that back, I can see how `async/await` will actually help without requiring a substantial rewrite! – Jaromanda X Mar 30 '18 at 08:09
  • 1
    FYI - `processed.then(data => { resolved(data); }).catch(err => {rejected(err);})` === `processed.then(resolved, rejected);` – Jaromanda X Mar 30 '18 at 08:13
  • @JaromandaX Yes, codes below inipromise runs before inipromise is finished properly – Maeror Mar 30 '18 at 08:36
  • @Svenskunganka I don't really know how to use async await, could you please provide some link so that I can learn and implement it? – Maeror Mar 30 '18 at 08:37
  • the "duplicate question" won't help you - because that deals with jquery rubbish ... – Jaromanda X Mar 30 '18 at 08:37
  • 1
    see if [this pastebin code](https://pastebin.com/Ff1bS87s) helps you at all - it uses async/await in the `conversation.message(payload` callback – Jaromanda X Mar 30 '18 at 08:38
  • @JaromandaX Thanks, async/await was def what we needed. Thank you so much! XOXO – Maeror Mar 30 '18 at 08:57
  • @JaromandaX Dear Jaromanda, WATSON nodejs sdk does not support async/await... is there any other approach? – Maeror Mar 31 '18 at 08:08

0 Answers0