My controller contains an asynchronous method that is supposed to set a results object. However, I'm facing an issue where instead of waiting for the 'await' to finish executing, the code jumps to the response object call prematurely, leaving the necessary variable undefined. Even in the debugger, the breakpoints in the intended method are hit after encountering the undefined error. I'm puzzled as to why the async await mechanism isn't functioning as expected here. Can anyone shed some light on this?
Controller class method:
public async loginUser(req: Request, res: Response) {
const { name, password } = req.body;
let result: ILoginResult = await UserData.login(name, password); // always turns out to be undefined
res.status(result.status).send(result.result); // gets executed before 'result' is properly set
}
UserData class:
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import mongoose from 'mongoose';
import ILoginResult from './ILoginResult';
import UserModel from '../../models/UserModel';
class UserData {
private connUri: string;
constructor() {
this.connUri = process.env.MONGO_LOCAL_CONN_URL;
}
public async login(name: string, password: string) {
try {
await mongoose.connect(this.connUri, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, }, (err) => {
let result: ILoginResult = { status: 0, result: null, error: '', token: '' };
let status = 200;
if (!err) {
UserModel.findOne({ name }, (err, user) => {
if (!err && user) {
bcrypt.compare(password, user.password).then(match => {
if (match) {
status = 200;
const payload = { user: user.name };
const options = { expiresIn: '2d', issuer: 'http://localhost' };
const secret = process.env.JWT_SECRET;
const token = jwt.sign(payload, secret, options);
result.token = token;
result.status = status;
result.result = user;
} else {
status = 401;
result.status = status;
result.error = `Authentication error`;
}
return result;
}).catch(err => {
status = 500;
result.status = status;
result.error = err;
return { status: status, result: result };
});
} else {
status = 404;
result.status = status;
result.error = err;
return result;
}
});
} else {
status = 500;
result.status = status;
result.error = err.toString();
return result;
}
});
} catch (e) {
let result: ILoginResult;
result.error = e.toString();
result.status = 500;
return result;
}
}
}
export default new UserData();