0

I tried using await to make my asynchronous function works like synchronous task, it works for regular function. But this doesn't work on my anonymous function.

So I have this function in my mongoose schema:

userSchema.methods.comparePassword = function comparePassword(candidatePassword, cb) {
  bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
    cb(err, isMatch);
  });
};

I tried to validate my hashed password using bcrypt.compare which requires me to use anonymous function to get the result.

So I tried to compare password using this function:

async (email, password, h) => {
    const user = await User.findOne({email: email, isDeleted: false})
    if (!user) {
        const data = ResponseMessage.error(400, User Not Found')
        return h.response(data).code(400)
    }
    await user.comparePassword(password, (err, isMatch) => {
        if (isMatch) {
            console.log('TRUE')
            return h.response('TRUE')
        } else if (!isMatch) {
            console.log('FALSE')
            return h.response('FALSE')
        }
    })
    console.log('END OF FUNCTION')
    return h.response('DEFAULT')
}

Attachment:

Response

Console

I tried to run the server and comparing the password, but it gives me the result of DEFAULT. I tried debugging using console then it shows TRUE/FALSE is showing after END OF FUNCTION. So it prooves my function is working well but my await function didn't wait my task to run another line.

Any help for my this?

Hariansyah
  • 13
  • 2
  • It's called a `callback-style` function, which is **not** a `Promise`, so you cannot use `await` here. You need to turn the `callback-style` function into a `Promise` if you want to utilize `async/await`. – goto Apr 16 '21 at 22:27
  • Does this answer your question? [How do I convert an existing callback API to promises?](https://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises) – goto Apr 16 '21 at 22:27
  • you can add your images with preview, not as a link – srknzl Apr 17 '21 at 08:11
  • @srknzl stackoverflow didn't allows me because I'm new user – Hariansyah Apr 17 '21 at 10:18
  • check out https://meta.stackoverflow.com/questions/344851/how-do-you-add-a-screenshot-image-to-your-stack-overflow-post – srknzl Apr 17 '21 at 10:23

2 Answers2

0

try to assign this to a Promise, like so:

userSchema.methods.comparePassword = async (candidatePassword, cb) => {
await new Promise ((resolve, reject)=>{
 bcrypt.compare(candidatePassword, this.password, (err, isMatch) => {
    resolve(cb(err, isMatch));
  });

})
};
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
0

You've supplied a callback to the compare function. The bcrypt docs say

"Async methods that accept a callback, return a Promise when callback is not specified if Promise support is available."

Promise support is probably available, so try not returning a callback and it looks like it should work. :-)

If you come across later APIs which aren't Promise-aware, by the way, you might want to look at Node's util.promisify function. It converts them to Promise-based functions. From the linked docs:

const util = require('util');
const fs = require('fs');
const stat = util.promisify(fs.stat);
const stats = await stat('.');
PaulW
  • 449
  • 1
  • 4
  • 9