1

Im using bcrypt and I'm trying to use an async function that hashes a password and returns it but since its async unless I use the sync version (which I don't want even though it works) it returns [object Promise] and the database saves this: {} as the password. Yes two brackets. I do use await but it does not work and my poor understanding of async functions is getting in the way. I can't find any answers online since it looks like I'm doing it all right according to the tutorials but I obviously am not.

The code looks like this:

function signup(){
     var pass = "example";
     pass = hashPassword(pass);
     
     console.log(pass); // prints [object Promise] - It's printed first.

     //write account with pass to database. Pass is saved as '{}'.
}

async function hashPassword(original_password){
     const hashedPass = await bcrypt.hash(original_password, 10);
     console.log(hashedPass) // prints the actual hashed pass - It's printed second

     return hashedPass; //returns [object Promise]
}

So how can I have it return the hashed password without adding the send-to-database code inside the async?

Nick
  • 67
  • 1
  • 10
  • 1
    you have to use . then to resolve a promise. check this out https://stackoverflow.com/questions/47469219/how-to-return-value-from-a-promise-thats-inside-another-function – vithu shaji Sep 23 '20 at 00:18

2 Answers2

2

bcrypt.hash does not return a promise.

You may need to wrap this function call into a new promise

const hashedPass = await new Promise((resolve, reject) => {
    bcrypt.hash(original_password, rounds, function(err, hash) {
      if (err) reject(err)
      resolve(hash)
    });
WhoAmI
  • 135
  • 8
  • Do I not use return somewhere in this case? I tried wrapping it before because i saw the same suggestion online but instead of `resolve(hash)` I had `return hash`. – Nick Sep 23 '20 at 08:56
  • If i try exactly what you did it returns [object Promise] again – Nick Sep 23 '20 at 09:14
2

When you call an async function it will return a promise, check out this answer on SO.

In order to get your hashed data you can use .then to resolve your promise

hashPassword(pass).then(hash=>console.log(hash)).catch(err=>console.error(err))

Or you can use async/await as well

async function signup() {
  try {
    var pass = "example";
    pass = await hashPassword(pass);
  } catch (err) {
    console.error(err);
  }
}
Shivam
  • 3,514
  • 2
  • 13
  • 27
  • Thank you. I tried doing this `var pass = data.pass.trim(); hashPass(pass).then((hash) => {pass = hash;}).catch(err=>console.error(err)); console.log("passtest:" + pass)` and it logs the originalPass instead of the hashed one. The hash function is this: `async function hashPass(originalPass){ const saltRounds = 10; const hashedPass = await bcrypt.hash(originalPass, saltRounds); return hashedPass; }` – Nick Sep 23 '20 at 08:52
  • 1
    This will return `original password` because `console.log` runs before `hashPass` executes as you cannot access `async` variables outside the `then()` block – Shivam Sep 23 '20 at 15:24
  • Oh so you are saying that i should send the password to the database WHILE i am inside the `.then()` ?? I only used the `.then()` to set `pass = hash` and use the new pass later outside the `.then()` – Nick Sep 23 '20 at 15:32
  • You can use `async/await` version to meet your needs but if you are using `then()` you have to do it inside the `.then() block` – Shivam Sep 23 '20 at 15:38
  • ok thank you for your time, thats what i needed. I accepted your answer then. – Nick Sep 23 '20 at 17:25