5

I am trying to query mssql database to get password for the user, that is sending post request and then just show it in console. But the promise I've made isn't working the way I wanted to and the password isn't loaded into the variable. Here's my code:

app.post('/test', function () {
    let user = 'User';
    let query = 'SELECT [Password] as password FROM [Table] where [User] = ' + SqlString.escape(user);

    let password = (async function () {
        try {
            let pool = await sql.connect(dbConfig);
            let result = await pool.request()
                .query(querys);
            console.dir(result.recordset[0].password) //Value here is OK
            return result.recordset[0].password
        } catch (err) {
            // ... error checks
        }
    })()
    console.log(password); //here I am getting "Promise { pending }"
});

The result I get is: Promise { pending } 'DatabasePassword'

Dodzik
  • 360
  • 9
  • 24
  • 2
    `let password = await (async function() {...} ())` as you are creating a promise with the `async` you need to `await` for it – nicowernli Jan 23 '18 at 14:56
  • Seen as your using `async`, just mark `app.post` as an `async` method then you can use `await` from the start.. `app.post('/test', async function () {` No need for the anonymous function. – Keith Jan 23 '18 at 14:57
  • This will only work if the web framework used supports async middleware handlers. Express does not support that yet i think. Koa does. – Spetastium Jan 23 '18 at 15:00
  • 1
    It works fine with `express`.. The Promise is ignored, and you just handle the errors inside,.. I'll post an example.. – Keith Jan 23 '18 at 15:03
  • With Koa though, you could actually assign async callbacks as middlewares and not have to do explicit error catching like this and the generic error handling middleware will handle it for you since Koa natively supports async/await. – Spetastium Jan 23 '18 at 15:13
  • @Spetastium Yes, it would be nice if you could just return a Promise in express,.. Not sure if it's on there todo list, be nice if it was.. :) ps. I think I've used KOA before, I liked it as it has a lot of stuff I don't use taken out, I think express still has the templating built in, something I don't use. – Keith Jan 23 '18 at 15:14
  • For express it seems like it will be included in version 5: https://github.com/expressjs/express/issues/2259#issuecomment-341604767 – Spetastium Jan 23 '18 at 15:21

3 Answers3

6

Here is an example of using async / await with express.

Express doesn't handle the errors, but that's no big problem you can handle them yourself, you could even wrap into a generic error handler to make things easier.

Anyway here is your code modified to use async/await in express.

app.post('/test', async function (req, res) {
  try {  
    const user = 'User';
    const query = 'SELECT [Password] as password FROM [Table] where [User] = ' + SqlString.escape(user);
    const pool = await sql.connect(dbConfig);
    const result = await pool.request()
      .query(querys);
    const password = result.recordset[0].password;
    console.log(password);
    res.end(password);
  } catch (e) {
    res.end(e.message || e.toString());
  }
});
Keith
  • 22,005
  • 2
  • 27
  • 44
  • Will express propagate errors thrown inside a promise? – Spetastium Jan 23 '18 at 15:05
  • 1
    Were handling the error, so nothing to propagate. You could do more fancy things with the error handling if you wanted. You could even do `async function (req, res, next)` and call `next(err)` to push to next handler.. – Keith Jan 23 '18 at 15:07
2

Had the same problem while using the MongoDB database, just made the post request async by adding keyword async to the function:

app.post('/register', async function(req,res){
  const myData = {username: req.body.name}
  const doesUserExists = await UserModel.exists(myData)
})
Shriya Madan
  • 151
  • 1
  • 7
1

Functions marked as async returns a promise. That is a wrapper around a future resolution (value or error). A function that returns a promise (which async functions does automatically) either has to be resolved as a promise by chaining .then(..) or by "unwrapping" it with await.

A function that somewhere in its code awaits an async function needs to be async itself. That means that whatever calls that function needs to await it or resolve it as a promise and so forth.

Spetastium
  • 205
  • 3
  • 12