1

I have some code like this:

let addUser = (req, res) => {
    let user;
    let message = "";
    let status = 200;

    bcrypt.hash(password, salt_rounds, (err, hash) => {
        user = new user({
            ...
            password: hash,
        });

        user.save(err => {
            if(err) {
                message = "No success";
                status = 400;
            } else {
                message = "success";
            }
        });

        res.status(status).json({
            message: message,
        });
    });
};

However, the message variable is undefined when the response is sent. I've been searching for a while now and, unfortunately, haven't been able to find a solution similar to this problem.

Ultimately, what I would like is to be able to update the message, status, etc. variables within the bcrypt/.save closures. I have tried using callbacks and resolving promises which I'm assuming didn't work due to naivety. Regardless, any solution would be appreciated!

Note: I would not like to use any other libraries to solve this problem (which I really doubt is required in the first place)

Thanks in advance!

Sam Gomena
  • 1,450
  • 11
  • 21
  • The issue is timing. `.save()` operates asynchronously and invokes the callback you're giving it *eventually*, pushing it out of the order that your code is written. The effect is that `let message` is being assigned a value after `res.json()` has already read `undefined` from it. – A quick solution would be to move `res.json()` so that it's inside the `.save()` callback. – Jonathan Lonowski May 11 '18 at 06:42

2 Answers2

1

Change user.save into something that returns a Promise, and then call .then on that Promise:

let addUser = (req, res) => {
  let user;
  let status = 200;

  bcrypt.hash(password, salt_rounds, (err, hash) => {
    user = new user({
      password: hash,
    });

    const savePromise = new Promise((resolve, reject) => {
      user.save(err => {
        if (err) {
          status = 400;
          reject("No success");
        } else {
          resolve("success");
        }
      });
    });
    savePromise.then(message => 
      res.status(status).json({ message })
    ).catch(message => 
      res.status(status).json({ message })
    );
  });
};
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
0

Try this, put message key in double quotes

let addUser = (req, res) => {
    let user;
    let message = "";
    let status = 200;

    bcrypt.hash(password, salt_rounds, (err, hash) => {
        user = new user({
            ...
            password: hash,
        });

        user.save(err => {
            if(err) {
                message = "No success";
                status = 400;
            } else {
                message = "success";
            }
        });

        res.status(status).json({
            "message": message,
        });
    });
};