When I get to the end of the code below, it always returns "undefined" and I don't know why!
function UserLogged (session) {
if (session === null) {
var err = new Error('Not logged in');
err.status = 400;
return {user : null, err : err};
}
User.findById(session.userId)
.exec(function (error, user) {
if (error) {
return {user : null, err : error};
}
else {
if (user === null) {
var err = new Error('Not authorized!');
err.status = 400;
return {user : null, err : err};
}
else {
console.log("User found and ok!");
return {user : user, err : null};
}
}
});
}
It does log "User found and ok!" on the console, but still returns "undefined"
UserLogged is Asynchronous function so one way to handle is to add a callback:
function UserLogged (session, next) {
if (session === null) {
var err = new Error('Not logged in');
err.status = 400;
return next({user : null, err : err});
}
User.findById(session.userId)
.exec(function (error, user) {
if (error) {
return next({user : null, err : error});
}
else {
if (user === null) {
var err = new Error('Not authorized!');
err.status = 400;
return next({user : null, err : err});
}
else {
console.log("User found and ok!");
return next({user : user, err : null});
}
}
});
}
and then you call UserLogged like this:
something.UserLogged(sessionData, function(result) {
console.log(result)
})
Related
I am writing mysql query with transaction but its not waiting to be completed and returns the result even before the function has executed.
Can someone please help me to know how to make function to wait for response?
The calling function is something like this:
deductUserPoint = await helper.deductUserPoint2(data)
console.log('===============================================')
console.log(deductUserPoint)
if (deductUserPoint.isError === true) {
let error = {}
error.isError = true
error.message = 'Unable to deduct amount'
error.error = deductUserPoint.error
res.status(200).json(error)
} else {
res.status(200).json({ 'isError': false, 'message': 'success' })
}
I always get deductUserPoint as undefined because it does not wait for deductUserPoint2 to return response
The deductUserPoint2 is as follows:
async deductUserPoint2(params) {
try {
this.db.connection.getConnection(function(err, conn) {
console.log('1111111111')
conn.beginTransaction(function(err) {
if (err) {
throw err
}
console.log(params)
console.log('2222222222')
conn.query('SELECT id, `expert_id`, user_id, status FROM `call` WHERE `id` = ?', [params.callId], function (error, callInfo, fields) {
if (error) {
return conn.rollback(function() {
throw error
})
}
console.log('33333333')
let callLength = null
if (params.callMinute === 'entire_day') {
callLength = 'entire_day'
} else {
const callMinutes = Math.round(params.callMinute)
if (callMinutes <= 30) {
callLength = '30_min'
} else if (callMinutes >= 31 && callMinutes <= 60) {
callLength = '60_min'
} else if (callMinutes >= 61 && callMinutes <= 90) {
callLength = '90_min'
} else if (callMinutes >= 91) {
callLength = '120_min'
}
}
console.log('4444444444')
conn.query('SELECT `amount` FROM `expert_charges` WHERE `status` = "active" AND `call_length` = ? AND `expert_id` = ?', [callLength, callInfo[0].expert_id], function (error, points, fields) {
if (error) {
return conn.rollback(function() {
throw error
})
}
console.log('555555555555')
let data = {
fromUserId: callInfo[0].user_id,
fromUserType: 'user',
to_user_id: 0,
to_user_type: null,
category: 'call',
type: 'debited',
callId: params.callId,
amount: points[0].amount,
note: params.note,
point: points[0].amount,
current_balance_point: 0
}
let input = Object.values(data)
conn.query('INSERT INTO wallet (`from_user_id`, `from_user_type`, `to_user_id`, `to_user_type`, `category`, `type`, `call_id`, `amount`, `note`, `point`, `current_balance_point`) VALUES ?', [[input]], function (error, wallet, fields) {
if (error) {
return conn.rollback(function() {
throw error
})
}
console.log('666666666666')
conn.query('UPDATE user SET total_points = total_points - ? WHERE id = ?', [points[0].amount, callInfo[0].user_id], function (error, updateUserPoint, fields) {
if (error) {
return conn.rollback(function() {
throw error
})
}
console.log('7777777777')
conn.commit(function(err) {
if (err) {
return conn.rollback(function() {
throw err
})
}
console.log('888888888')
return {
"isError": false,
"status": "success"
}
})
})
})
})
})
})
})
} catch (error) {
console.log(error)
return {
"isError": true,
"error": error.toString()
}
}
Error it prints is :
undefined
(node:4197) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'isError' of undefined
at router.post (/Users/msmexmac/node/msmex-backend/msmex-api/api/wallet.js:120:23)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:4197) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:4197) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
1111111111
{ callId: 5, note: 'Deduction for call', callMinute: 25 }
2222222222
33333333
4444444444
555555555555
666666666666
7777777777
888888888
You can't use async functions like that, you have to return a promise to be able to wait for your callbacks. Your function would have to end up like this:
function deductUserPoint2(params) {
return new Promise(function (resolve, reject) {
try {
this.db.connection.getConnection(function (err, conn) {
console.log('1111111111')
conn.beginTransaction(function (err) {
if (err) {
return reject(err)
}
console.log(params)
console.log('2222222222')
conn.query('SELECT id, `expert_id`, user_id, status FROM `call` WHERE `id` = ?', [params.callId], function (error, callInfo, fields) {
if (error) {
return conn.rollback(function () {
return reject(error)
})
}
console.log('33333333')
let callLength = null
if (params.callMinute === 'entire_day') {
callLength = 'entire_day'
} else {
const callMinutes = Math.round(params.callMinute)
if (callMinutes <= 30) {
callLength = '30_min'
} else if (callMinutes >= 31 && callMinutes <= 60) {
callLength = '60_min'
} else if (callMinutes >= 61 && callMinutes <= 90) {
callLength = '90_min'
} else if (callMinutes >= 91) {
callLength = '120_min'
}
}
console.log('4444444444')
conn.query('SELECT `amount` FROM `expert_charges` WHERE `status` = "active" AND `call_length` = ? AND `expert_id` = ?', [callLength, callInfo[0].expert_id], function (error, points, fields) {
if (error) {
return conn.rollback(function () {
return reject(error)
})
}
console.log('555555555555')
let data = {
fromUserId: callInfo[0].user_id,
fromUserType: 'user',
to_user_id: 0,
to_user_type: null,
category: 'call',
type: 'debited',
callId: params.callId,
amount: points[0].amount,
note: params.note,
point: points[0].amount,
current_balance_point: 0
}
let input = Object.values(data)
conn.query('INSERT INTO wallet (`from_user_id`, `from_user_type`, `to_user_id`, `to_user_type`, `category`, `type`, `call_id`, `amount`, `note`, `point`, `current_balance_point`) VALUES ?', [[input]], function (error, wallet, fields) {
if (error) {
return conn.rollback(function () {
return reject(error)
})
}
console.log('666666666666')
conn.query('UPDATE user SET total_points = total_points - ? WHERE id = ?', [points[0].amount, callInfo[0].user_id], function (error, updateUserPoint, fields) {
if (error) {
return conn.rollback(function () {
return reject(error)
})
}
console.log('7777777777')
conn.commit(function (err) {
if (err) {
return conn.rollback(function () {
return reject(err)
})
}
console.log('888888888')
return resolve({
"isError": false,
"status": "success"
})
})
})
})
})
})
})
})
} catch (error) {
console.log(error)
return resolve({
"isError": true,
"error": error.toString()
})
}
})
}
Then you use reject(err) instead of throw err and resolve(value) instead of return value.
Another approach is using utils.promisify as #georg suggested.
I would like to know how to send error code in promise as response in nodejs. Error in Promise Not sending any error in response object in NodeJS/Express
module.exports.providerData = function (reqUrl, query) {
return new Promise(async function (resolve, reject) {
try {
var validUrl = checkValidParamters(reqUrl, query);
if(validUrl != true){
throw new Error('failed');
}
else{
sendcountry = countryjson.filter(function (send) {
return send.country_name == param_sendcountry;
})
var provider_sendcncode = sendcountry[0].country_code;
var receive = countryjson.filter(function (pr) {
return pr.country_name == param_receivecountry;
})
var valid = true;
var valid_obj = { validstatus: valid};
resolve(valid_obj);
}
}
catch (err) {
reject(err);
}
});
}
in app.js
router.get('/', function (req, res, next) {
if (getcountries == null && getcurrencies == null && getproviders == null) {
util.providerData(req.originalUrl, req.query).then(obj => {
res.render("corridor.ejs");
}).catch(err=>{
res.status(401).send({ error : err.message });
})
}
else {
console.log('just return');
util.providerData(req.originalUrl, req.query).then(obj => {
res.render("corridor.ejs");
}).catch(err=>{
res.status(401).send({ error : err.message });
})
}
});
I need to catch the error response res.status(401).send({ error : err.message }); if export function is returning false/error
your promise doesn't resolve anything. to resolve, you just simple return your response.
router.get('/', function (req, res, next) {
if (getcountries == null && getcurrencies == null && getproviders == null) {
return util.providerData(req.originalUrl, req.query).then(obj => {
return res.render("corridor.ejs");
}).catch(err=>{
return res.status(401).send({ error : err.message });
})
}
else {
console.log('just return');
return util.providerData(req.originalUrl, req.query).then(obj => {
return res.render("corridor.ejs");
}).catch(err=>{
return res.status(401).send({ error : err.message });
})
}
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I'm using the 'user-management' package in Node, and I have a callback within a callback, within a callback. But the final result doesn't return. This is my main NodeJS module:
playerManagement.login(data.username, data.pw, function (result) {
console.log(result) <-- statement never reached
if (result == "fail") {
socket.emit('client', { type: 'login', result : 'fail'});
} else {
connections[playerindex++] = {'username' : username, 'sockid' : socket.id, 'token' : result };
socket.emit('client', { type: 'login', result : 'success', username : username });
console.log(connections);
}
});
Then I have an external module with the function:
playerModule.prototype.login = function(username, password) {
var o = this;
o.user.load(function (err) {
if (!err) {
o.user.authenticateUser(username, password, function(err, result) {
if (!result.userExists) {
console.log('Invalid username');
return "fail";
} else if (!result.passwordsMatch) {
console.log('Invalid password');
return "fail";
} else {
console.log('User token is: ' + result.token); <--- this is reached.
return result.token;
}
});
} else {
console.log('error logging in');
return "fail";
}
});
So I'm guessing I need to return the value to the "load" function callback, but I'm not sure how to do that.
Change the definition of login with the following.
playerModule.prototype.login = function(username, password, callback) {
var o = this;
o.user.load(function (err) {
if (!err) {
o.user.authenticateUser(username, password, function(err, result) {
if (!result.userExists) {
console.log('Invalid username');
return callback("fail");
} else if (!result.passwordsMatch) {
console.log('Invalid password');
return callback("fail");
} else {
console.log('User token is: ' + result.token); <--- this is reached.
return callback(result.token);
}
});
} else {
console.log('error logging in');
return callback("fail");
}
});
Hi I am trying to use the Async module to retrieve two users and do some processing after they have both been retrieved however I keep getting the error message: Callback was already called. Below is the code i currently have:
app.get('/api/addfriend/:id/:email', function(req, res) {
var id = req.params.id;
var friendEmail = req.params.email;
async.parallel([
//get account
function(callback) {
accountsDB.find({
'_id': ObjectId(id)
}, function(err, account) {
console.log(id);
if (err || account.length === 0) {
callback(err);
}
console.log(account[0]);
callback(null, account[0]);
});
},
//get friend
function(callback) {
accountsDB.find({
'email': friendEmail
}, function(err, friend) {
console.log(friendEmail);
if (err || friend.length === 0 || friend[0].resId === undefined) {
callback(err);
}
console.log(friend[0]);
callback(null, friend[0].resId);
});
}
],
//Compute all results
function(err, results) {
if (err) {
console.log(err);
return res.send(400);
}
if (results === null || results[0] === null || results[1] === null) {
return res.send(400);
}
//results contains [sheets, Friends, Expenses]
var account = results[0];
var friend = results[1];
if (account.friends_list !== undefined) {
account.friends_list = account.friends_list + ',' + friend;
}
else {
account.friends_list = friend;
}
// sheetData.friends = results[1];
accountsDB.save(
account,
function(err, saved) {
if (err || !saved) {
console.log("Record not saved");
}
else {
console.log("Record saved");
return res.send(200, "friend added");
}
}
);
}
);
});
Any help would be appreciated.
Add else statement to your code, because if you get error, your callback executes twice
if (err || account.length === 0) {
callback(err);
} else {
callback(null, account[0]);
}
The docs from async actually say:
Make sure to always return when calling a callback early, otherwise
you will cause multiple callbacks and unpredictable behavior in many
cases.
So you can do:
return callback(err);
I wanna return the MySQL query in Node.js, but I got some problems.
Prob1. 'var userInfo' cannot get the value from function 'Authenticate()'
Prob2. The throw will be catched by 'dbclient.query', not my code you can see.
Hope guys can help me.
app.post('/create_member_check', function(req, res) {
var Authenticate = function () {
SearchUser(req.body.email, function (isExist) {
if (isExist === true)
throw 101;
else if (req.body.email === undefined || req.body.email == "")
throw 102;
else if (req.body.password === undefined || req.body.password == "")
throw 103;
else if (isExist === undefined)
throw 104;
var user = {
"email": req.body.email,
"password": req.body.password
};
AddUser(user);
// This line cannot return the 'user' for 'Authenticate()' caller.
return user;
});
}
try {
var userInfo = Authenticate();
}
catch (err) {
var userInfo;
if (err == 101)
userInfo = "[Error] This account already exists.";
else if (err == 102)
userInfo = "[Error] Please key in 'email'.";
else if (err == 103)
userInfo = "[Error] Please key in 'password'.";
else if (err == 104)
userInfo = "[Fatal Error] SearchUser return 'undefined'.";
}
res.render("login_system/create_member_check", {
layout: false,
pagename: "create",
authenticate: userInfo
});
});
SearchUser = function (email, callback) {
dbclient.query("SELECT * FROM user WHERE email = \"" + email + "\"", function (err, results) {
if (err || results.length <= 0)
callback(false);
else
callback(true);
});
}
Authenticate method can't be synchronous. You should make asynchronous method. Try this.
app.post('/create_member_check', function(req, res) {
var Authenticate = function (req, callback) {
SearchUser(req.body.email, function (isExist) {
if (isExist === true)
return callback(101);
else if (req.body.email === undefined || req.body.email == "")
return callback(102);
else if (req.body.password === undefined || req.body.password == "")
return callback(103);
else if (isExist === undefined)
return callback(104);
var user = {
"email": req.body.email,
"password": req.body.password
};
AddUser(user); //this is maybe asynchronous, again
callback(null, user);
});
}
Authenticate(req, function(err, user){
var userInfo;
if (err == 101)
userInfo = "[Error] This account already exists.";
else if (err == 102)
userInfo = "[Error] Please key in 'email'.";
else if (err == 103)
userInfo = "[Error] Please key in 'password'.";
else if (err == 104)
userInfo = "[Fatal Error] SearchUser return 'undefined'.";
res.render("login_system/create_member_check", {
layout: false,
pagename: "create",
authenticate: userInfo
});
});
});
And read this article ;)