0

I have this function that is supposed to authenticate a user and return a WT token:

async function authenticate({username, password}) {

    userModel.find({username: username, password: password}, (err, doc) => {
      if (doc[0]) {

        const user = {
            id: doc[0]._id,
            username: doc[0].username,
            password: doc[0].password,
            firstName: doc[0].firstName,
            lastName: doc[0].lastName,
            role: doc[0].role
        };

        const token = jwt.sign({sub: user.id, role: user.role}, config.secret);
        const {password, ...userWithoutPassword} = user;
        return {
            ...userWithoutPassword,
            token
        };
    }
  });
}

userModel is a mongoose model. The return statement at the end seems not to return anything but doing console.log inside it, the values are filled correctly. Am I missing something? I am at the first attempts with node so if anything is not clear please ask.

I checked out the suggested previous solution but I don't understand how to apply it to my specific case.

user3174311
  • 1,714
  • 5
  • 28
  • 66
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – 1565986223 May 05 '19 at 14:56

3 Answers3

0

Wrap userModel in Promise, then you can await it

async function authenticate({ username, password }) {
  return await new Promise(function(resolve) {
    userModel.find({ username: username, password: password }, (err, doc) => {
      if (doc[0]) {
        const user = {
          id: doc[0]._id,
          username: doc[0].username,
          password: doc[0].password,
          firstName: doc[0].firstName,
          lastName: doc[0].lastName,
          role: doc[0].role
        };

        const token = jwt.sign(
          { sub: user.id, role: user.role },
          config.secret
        );
        const { password, ...userWithoutPassword } = user;
        resolve({
          ...userWithoutPassword,
          token
        });
      }
    });
  });
}

SIMDD
  • 615
  • 5
  • 15
0

You need to use async and await instead of using callbacks:-

async function authenticate({username, password}) {
  try {
    const doc = await userModel.findOne({username: username, password: password});
   if (doc) {

        const user = {
            id: doc._id,
            username: doc.username,
            password: doc.password,
            firstName: doc.firstName,
            lastName: doc.lastName,
            role: doc.role
        };

        const token = jwt.sign({sub: user.id, role: user.role}, config.secret);
        const {password, ...userWithoutPassword} = user;
        return {
            ...userWithoutPassword,
            token
        };
    }
  } catch(err) {
    // handle error
  }
}
cEeNiKc
  • 1,308
  • 7
  • 13
  • thanks @cEeNiKc that's what I needed. Thanks everyone all the proposed solutions work fine but I could approve only one. – user3174311 May 05 '19 at 16:47
  • You're welcome. Just one more suggestion, you can use findOne instead of find method which will return a single user object instead of an array of users. I have updated the answer. – cEeNiKc May 05 '19 at 16:56
0

Mongoose 5.0 will use native promises by default if available, otherwise no promises. You will still be able to set a custom promises library using mongoose.Promise = require('bluebird');, however, mpromise will not be supported.

Mongoose 5.x

async function authenticate({ username, password }) {

  let doc = await userModel.find({ username: username, password: password }).exec(); // exec() convert query to a native Promise.

  if (doc[0]) {

    const user = {
      id: doc[0]._id,
      username: doc[0].username,
      password: doc[0].password,
      firstName: doc[0].firstName,
      lastName: doc[0].lastName,
      role: doc[0].role
    };

    const token = jwt.sign({ sub: user.id, role: user.role }, config.secret);
    const { password, ...userWithoutPassword } = user;
    return {
      ...userWithoutPassword,
      token
    };
  }
  // else ?
  return null;
}
hoangdv
  • 15,138
  • 4
  • 27
  • 48