how can i get value out of a child function [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
var checkAcount = (usr, pass) => {
var sql = "SELECT * FROM account WHERE userName = '" +usr+"'" ;
con.query(sql, (err, result) => {
if(err) throw err;
if(result.length > 0){
bcrypt.compare(pass, result[0].password, function(err, result1) {
if(result1 == true){
return true;
}
else{
return false;
}
});
}
else {
return false;
}
});
return ???;
}
I have code like this and I don't know how to make this function return the value of the compare function (true or false). Add return in child function like I did seem not to work. Can somebody help me please.

You could return a promise:
async function checkAcount(usr, pass) => {
const sql = "SELECT * FROM account WHERE userName = ?" ;
return new Promise((resolve, reject) => {
con.query(sql, [usr], (err, result) => {
if(err) {
reject(err);
throw err;
}
if(result.length > 0){
bcrypt.compare(pass, result[0].password, function(err, result1) {
if(result1 == true){
resolve(result);
return true;
} else{
reject(err);
return false;
}
});
} else {
reject(err);
return false;
}
});
});
}
Don't build your SQL query with string concatenation. That allows SQL injection.

bcrypt returns a promise
https://www.npmjs.com/package/bcrypt#with-promises
bcrypt.compare(pass, result[0].password).then((result) => {
return result;
})

Related

function returns undefined value [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have a function named IsValidUrl() that I need that returns some values by its situation(false or true). But inside of this function I have another function that won't let to pass the values to IsValidUrl().
var validUrl = await isValidUrl();
if (!validUrl) {
console.log(validUrl); ** //validUrl is undefined**
return res.status(404).send('not found');
}
function isValidUrl() {
Post.findOne({
url: req.params.path
}, function(err, result) {
if (err) {
throw err
} else if (!result) {
return false
} else {
return true
}
})
}
How can I send the returned values to the IsValidUrl()?
function isValidUrl() {
return new Promise((resolve, reject) => {
Post.findOne({
url: req.params.path
}, function(err, result) {
if (err) {
reject(err);
} else if (!result) {
resolve(false);
} else {
resolve(true);
}
})
})
}

mongodb nodejs store value outside connect

I need a way to store value outside mongoDB connect call:
read(object) {
let result
MongoClient.connect(this.url, function (err, db) {
if (err!=null){
result = err;
} else {
db.collection(object.collection).find(object.field).toArray(function(err, docs) {
assert.equal(err, null);
db.close();
result = docs;
});
}
});
return result
}
When i call this method, which is part of a class, return is called before result assignment, as normal.
Example: console.log(read(obj)) returns undefined
The idea is to store value in a variable and return might wait until connect terminate.
Is there any way to resolve this problem?
Without promise:
Call return inside find and err function:
read(object) {
let result
MongoClient.connect(this.url, function (err, db) {
if (err!=null){
result = err;
return result; //here
} else {
db.collection(object.collection).find(object.field).toArray(function(err, docs) {
assert.equal(err, null);
db.close();
result = docs;
return result; // here
});
}
});
}
Or set a timeout for return with enough time to wait for other process to end:
read(object) {
let result
MongoClient.connect(this.url, function (err, db) {
if (err!=null){
result = err;
} else {
db.collection(object.collection).find(object.field).toArray(function(err, docs) {
assert.equal(err, null);
db.close();
result = docs;
});
}
});
setTimeout(function(){ return result}, 3000); // 3secs
}
With Promise you can try the following:
function read(object) {
let result
return new Promise((resolve, reject) => {
MongoClient.connect(this.url, function (err, db) {
if (err!=null){
reject(err);
} else {
db.collection(object.collection).find(object.field).toArray(function(err, docs) {
db.close();
if (err) {
reject(err);
} else {
resolve(docs);
}
});
}
});
});
}
// then you can call the function and use the result like this
read(obj).then(docs => {
console.log(docs);
})
.catch(err => {
// handle error
console.log(err);
})

javascript mysql and promises

I'm working with promises, or at least trying to.
Here is what my code look's so far:
checkEmailUsername = function(mail, user) {
return new Promise(function(resolve, reject) {
var query;
query = "SELECT * FROM users WHERE email = ? OR username = ?";
return connection.query(query, [mail, user], function(err, row, fields) {
if (err) {
reject(err);
}
console.log(row.length);
if (row.length > 0) {
return resolve(true);
} else {
return resolve(false);
}
});
}).then()["catch"]();
};
Question is. How to return the resolve values from inside the promise?
You can't use return here, use the promise resolve function to return the rows from db to the caller.
checkEmailUsername = function (mail, user) {
return new Promise(function (resolve, reject) {
var query;
query = "SELECT * FROM users WHERE email = ? OR username = ?";
connection.query(query, [mail, user], function (err, row, fields) {
if (err) {
reject(err);
}
console.log(row.length);
resolve(row);
});
};
checkEmailUsername(mail, user).then(function (rows) {
// do something with the rows
}).catch((err) => {
//handle error
}
}

JavaScript/NodeJS Callback within a callback [duplicate]

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");
}
});

Mutable variable is accessible from closure with promise and loop

I use the following code to generate a unique token for a user. Data for users is stored on MongoDB so I use promise to handle asynchronous talking to the db. In WebStorm I receive this warning : Mutable variable is accessible from closure with promise and loop. and I know there have been posts on SO about this thing, but I my case is more complicated. I know I may not even need to worry about it as I only use the last value of token but what I want to solve this issue in a correct way ?
var generateToken = function(userId) {
User.findOne({userId: userId}, function(err, user) {
if (user !== null) {
var loop = true;
while (loop) {
var token = Common.randomGenerator(20);
User.find({tokens: token}, function(err, result) {
if (err) {
loop = false;
return Promise.reject('Error querying the database');
} else {
if (result.length === 0) {
if (user.tokens === undefined){
user.tokens.push(token);
}
loop = false;
return Promise.resolve(token);
}
}
});
}
} else {
return Promise.reject('UserNotFound');
}
});
};
I came up with the following solution , is it correct ?
var generateToken = function(userId) {
User.findOne({userId: userId}, function(err, user) {
if (user !== null) {
var loop = true;
while (loop) {
var token = Common.randomGenerator(20);
(function(e){
User.find({tokens: e}, function(err, result) {
if (err) {
return Promise.reject('Error querying the database');
} else {
if (result.length === 0) {
if (user.tokens === undefined){
user.tokens = [];
}
user.tokens.push(e)
return Promise.resolve(e);
}
}
});
})(token);
}
} else {
return Promise.reject('UserNotFound');
}
});
};
NOTE As #Alex Nikulin suggested , I flipped loop to false before sending back the result of the promise. But still it's an infinite loop as it doesn't go into the User.find({tokens: e})....
Your problem is that, return statement is within function, not within loop.Your loop is infinite. I has decomposited your code.Or simply make loop false, when you resolve/reject promise. Also my code will wait each answer from User, and error will gone. And your variant with wrap function is correct (function(e){})(token).
var generateToken = function(userId) {
return new Promise(function(resolve, reject) {
User.findOne({userId: userId}, function(err, user) {
if (user !== null) {
userTokenIterator(user,resolve, reject);
} else {
reject('UserNotFound');
}
});
});
};
var addTokenToUser = function(token,user){
return new Promise(function(resolve, reject) {
User.find({tokens: token}, function(err, result) {
if (err) {
reject('Error querying the database');
} else {
var result = result.length === 0;
if (result) {
if(!user.tokens) {
user.tokens = []
}
user.tokens.push(token);
}
resolve(result);
}
});
});
};
var userTokenIterator = function (user, resolve, reject){
var token = Common.randomGenerator(20);
addTokenToUser(token, user).then(function(result){
if(result) {
resolve(token);
}else{
userTokenIterator(user,resolve, reject)
}
},function(error){
reject(error);
});
};

Categories

Resources