Ad

Async/await Call Returns Undefined When Used In Conjunction With Promises

I am having an issue where an Async call to my database returns undefined. The function "findOne" retrieves one row from the database, but the .then(... function is executing before the row is returned.

I've tried changing what I return in the DB function findOne as well as adding an 'await' on the function call. I've also tried using Promise.resolve(db.findOne({requestbody}).then(... but no luck with that either.

Here is the db.findOne method

const findOne = async (req) => {
    const { teamId, channelId, isClosed } = req;
    return db.query('SELECT * FROM polls where team_id= $1 and channel_id =$2 and is_closed = $3 LIMIT 1',
        [teamId, channelId, isClosed],
        (error, results) => {
            if (error) {
                throw error;
            }
            console.log("\nDBRes: \n", results.rows[0])
            return results.rows[0];
        }
    );
};

And here is where I call the function

app.post('/', (req, res) => {
    const slashCommand = req.body.command;
    switch (slashCommand) {
//...
//... Some other code
//...
        case 'results':
            db.findOne({
                teamId: requestBody.team_id,
                 channelId: requestBody.channel_id,
                 isClosed: false,
            })
            .then((row) => {
                 console.log(row);
                 const poll = pollFuncs.getPollfromResultRow(row);
                 const displayText = pollFuncs.getFormattedPollResults(poll);
                 res.status(200).send({
                     text: displayText,
                 });
             });
         break;
//... The rest of the function

Here are the logs I am getting. Note* I am currently logging the "row" object both inside the .then(...) function and inside the pollFuncs.getPollfromResultRow(row); function

Bot is listening on port 3000
undefined
undefined
(node:14000) UnhandledPromiseRejectionWarning: TypeError: Cannot destructure property `id` of 'undefined' or 'null'.
    at Object.getPollfromResultRow (C:\Users\ztb0504\Documents\Projects\Node\werewolfmod\pollFunctions.js:97:125)
    at db.findOne.then (C:\Users\ztb0504\Documents\Projects\Node\werewolfmod\index.js:59:56)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:14000) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:14000) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

DBRes:
 { id: '22',
  poll_title: 'This is a new Pollstgresql',
  //The rest of the expected data....
 }

I'd appreciate any guidance on how to get this to return data as expected. Thank you!

Ad

Answer

You're mixing plain callbacks and promises and it is causing you problems. It will be a lot easier if you don't do that.

If you pass a plain callback to db.query(), then it won't return a promise. In fact, it will return nothing (undefined). So, when you do return db.query(), all you're doing is returning undefined.

Change to this:

const findOne = async (req) => {
    const { teamId, channelId, isClosed } = req;
    return db.query('SELECT * FROM polls where team_id= $1 and channel_id =$2 and is_closed = $3 LIMIT 1',
        [teamId, channelId, isClosed]).then(results) => {
            console.log("\nDBRes: \n", results.rows[0])
            return results.rows[0];
    });
};

The, you also need error handling in your request handler if there are any errors in the query. Promise handling should nearly always have a .catch() somewhere to handle errors:

                case 'results':
                    db.findOne({
                        teamId: requestBody.team_id,
                        channelId: requestBody.channel_id,
                        isClosed: false,
                    }).then((row) => {
                            console.log(row);
                            const poll = pollFuncs.getPollfromResultRow(row);
                            const displayText = pollFuncs.getFormattedPollResults(poll);
                            res.status(200).send({
                                text: displayText,
                            });
                    }).catch(err => {
                            console.log(err);
                            res.sendStatus(500);
                    });
                    break;
Ad
source: stackoverflow.com
Ad