Express: Resolved Promise going to catch Call - javascript

I am trying to send the data from a promise, using Promise chaining the Promise is getting resolved. But the catch call is running not then call
Here is the code from where I am returning the data using Promise:
UserSchema.statics.findByCredentials = function(email, password) {
const User = this;
return User.findOne({
email
}).then((user) => {
if(!user) {
return Promise.reject();
}
try {
return new Promise((reject, resolve) => {
bcrypt.compare(password, user.password, (err, res) => {
// console.log(res);
if(res)
resolve(user);
else
reject("Invalid Credentials");
});
});
}
catch(error) {
Promise.reject(error);
}
});
};
Here is the Promise chain call, where catch call is working not the then call
app.post('/users/login', (req, res) => {
const body = _.pick(req.body, ['email', 'password']);
// console.log(body);
User.findByCredentials(body.email, body.password)
.then((user) => {
}).catch(error => {
error.generateAuthToken().then((token) => {
res.header('x-auth',token).send(error);
});
});
});
Hi tweaked the code, to have another call on the catch.
Could be there any better solution for that.
It's sure that the data is being returned that means, Promise is resolved.

Related

findOneAndUpdate promise always resolving. Why?

I made email verification function and problem is that findOneAndUpdate function always resolve no matter what.
I have empty database, so I guess findOneAndUpdate function should fail, but it succeeds.
I guess my mistake is somewhere in this function
User.activate = function(activationLink) {
return new Promise(function(resolve, reject) {
usersCollection.findOneAndUpdate({"activationLink": activationLink}, {"$set": {"isActivated": true}}).then(function(userDoc) {
if (userDoc) {
resolve('Your account has been activated!')
} else {
reject('This account does not exist!')
}
}).catch((e) => {
reject(e)
})
})
}
I'll add this just in case.
userController.js:
exports.activate = function(req, res){
User.activate(req.params.activationLink).then((result) => {
res.send(result)
}).catch((e) => {
res.send(e)
})
}
router.js:
router.get('/activate/:activationLink', userController.activate)

Returning undefined result after awaiting function

I am trying to get the result back from function where the result is in the callback. However the result always come back as undefined even though I set it to be the res. Can someone explain why this does not work?
function getData(id, callback) {
return dataModel.findOne({ id }).exec((err, res) => {
if (err) return callback(err)
return callback(null, res)
})
}
async function middleware(req.body) {
try {
let result
await getData(req.body, (err, res) => {
if (err) throw err
result = res
})
await nextFunc(result)... // result is undefined
} catch (err) {
console.log(err)
}
}
You are using callbacks, but in order to make things work with async await you are supposed to use promises
Try
function getData(id, callback) {
return new Promise((resolve, reject) => {
dataModel.findOne({ id }).exec((err, res) => {
if (err) reject(err);
resolve(res);
});
});
}
async function middleware(req.body) {
try {
let result = await getData(req.body);
await nextFunc(result);
} catch (err) {
console.log(err);
}
}

How do I use aysnc/await in this superagent call?

This is a superagent call, I have imported request(i.e is exported from my superagent component class)
How do I use async/await in this for "res.resImpVariable".
request
.post(my api call)
.send(params) // an object of parameters that is to be sent to api
.end((err, res) => {
if(!err) {
let impVariable = res.resImpVariable;
} else {
console.log('error present');
}
});
I reformulated my answer. I think I was misinterpreting before. You could wrap the entire sequence into a Promise-returning function that resolves after the response callback:
function callSuperagent() {
return new Promise((resolve, reject) => {
return request
.post(my api call)
.send(params) // an object of parameters that is to be sent to api
.end((err, res) => {
if(!err) {
console.log('get response', res);
// uncomment this to see the catch block work
// reject('Bonus error.');
resolve(res);
} else {
console.log('error present', err);
reject(err);
}
});
});
}
Then, you can create an async function and await that:
async function doSomething() {
try {
const res = await callSuperagent();
// uncomment this to see the catch block work
// throw 'Artificial error.';
console.log('res', res);
console.log('and our friend:', res.resImpVariable);
} catch (error) {
throw new Error(`Problem doing something: ${error}.`);
}
}
doSomething();
Or if you don't make doSomething, it would be like this:
callSuperagent()
.then((res) => {
console.log('res', res);
console.log('and our friend:', res.resImpVariable);
})
.catch((err) => {
console.log('err', err);
})

why is await not working even when used in async function

I made a function to search a user by email id. I'm calling that function in an async function using await and assigning the returned value to or constant/variable but getting undefined on printing the constant/variable
function search(email) {
sql = `SELECT email FROM users WHERE email = '${email}'`;
db.query(sql, (err, res) => {
if (err) {
console.log(err);
}
else {
return res[0].email;
}
})
}
const auth = async (req, res, next) => {
try {
const token = req.header('Authorization').replace('Bearer', '');
const decoded = jwt.verify(token, 'catisdoguniversaltruth');
const user = await search(decoded._id);
console.log(user);
if (!user) {
throw new Error();
}
next();
}
catch (e) {
res.status(401).send("Not Authenticated, Please login");
}
};
module.exports = auth;
You need search() to be a promise and not a function.
await waits for a promise to resolve.
Try this:
function search(email) {
return new Promise((resolve, reject) => {
sql = `SELECT email FROM users WHERE email = '${email}'`;
db.query(sql, (err, res) => {
if (err) {
reject(err);
}
else {
resolve(res[0].email);
}
})
})
}
This will be resolved as promise and auth() will wait.
You could also build search() as async/await promise. Doesn't really matter as long as you return a promise resolve.

Error: TypeError: Cannot read property 'catch' of undefined when trying to register user for website node.js

I seem to have messed up one of my promises (I think) in a javascript function that is supposed to register a user. I have included the post request and the actual function itself.
app.post("/register", (req, res) => {
dataServiceAuth.registerUser(req.body).then(() => {
res.render("register", {successMessage: "User created"});
}).catch((err) => {
res.render("register", {errorMessage: err, user: req.body.user});
});
});
module.exports.registerUser = function (userData) {
return new Promise(function (resolve, reject) {
if (userData.password != userData.password2) {
reject("Passwords do not match");
}
else {
let newUser = new User(userData);
newUser.save((err) => {
resolve();
}).catch((err) => {
if (err) {
if (err.code == 11000) {
reject('User Name already taken');
}
else {
reject('There was an error creating the user: ${err}');
}
}
});
}
});
};
If newUser.save can return a promise, you definitely shouldn’t be passing a callback to it, or even using the Promise constructor at all. If you really want to reject with strings, the way to implement that would be by transforming rejections from newUser.save() with .catch into new rejections by returning them, and returning the resulting promise from registerUser:
module.exports.registerUser = function (userData) {
if (userData.password != userData.password2) {
return Promise.reject("Passwords do not match");
}
let newUser = new User(userData);
return newUser.save().catch((err) => {
if (err.code == 11000) {
return Promise.reject('User Name already taken');
}
else {
return Promise.reject('There was an error creating the user: ${err}');
}
});
};

Categories