Checking existing element in database with Node.js and MySQL - javascript

so here's the issue, everything inside the con.query(query, function (err, result, fields) is never called. So this is the part of code that is about verifying that when the user is signing up, the email that he took is not already taken. argv[0] contains the email that the user typed (it's not wrong, I debugged it). So I obviously created two accounts with the same email but the second one is never flagged (the function is continuing instead of returning "userexists").
var mysql = require('mysql');
var con = mysql.createConnection(Credentials). // 👈 The connection is established, it's not a problem.
var query = "SELECT id FROM accounts_data WHERE email = '" + argv[0] + "'";
var r;
con.query(query, function (err, result, fields) {
if (err)
return "failed";
if(result != undefined)
return "userexists" // The if is never checked
});
Thank you.
EDIT:
Hello everyone, so the console.log(results.length) is printing the right result, but how can I give the result to r? Because the last console.log(r) is still printing 0.
var r = 0;
var sql = 'SELECT * FROM accounts_data WHERE email = ' + con.escape(argv[0]);
con.query(sql, function (error, results, fields) {
if (error) throw error;
console.log(results.length); // Right result
r = results.length; // Not giving the result to r
});
console.log(r); // Not the right result

Try using Promise's, they'll help get away from 'callback-hell'
const userExists = async emailAddress => new Promise((resolve, reject) => {
con.query(`
SELECT EXISTS(
SELECT id FROM accounts_data WHERE email = ?
);
`,
[emailAddress],
(err, result) => {
if (err) { reject(err); }
resolve(result);
}
)
);
await userExists('abc#example.com') // => boolean

Related

Async mysql query in nodejs

I have been struggling for a few days with a problem that seems simple to me. I want to insert a value if it does not exist in a mysql database with nodejs.
I have an array of array, and I need to loop inside a child to check every data.
Example of data
finalRow = [['a > 'b'], ['a' > 'c']];
My code
for(let i=0; i < finalRow.length-1; i++) {
var splitcat = finalRow[i].split(' > ');
(async function(){
for(let j=0; splitcat.length-1; j++) {
var query = "SELECT * from category where name = '" + splitcat[j] + "'";
await con.query(query, async function (err, result, fields) {
if (err) throw err;
if(result && result.length) {
console.log("nothing");
} else {
console.log("insert into db");
await con.query(`INSERT INTO category (name, url, description, parent_id) VALUES (?, ?, ?, ?)`,
[splitcat[j], '', '', null], function (err, result) {
if (err) throw err;
});
}
});
}
})();
I tried several versions of this code, but
the loop does not wait for the existence check and inserts all the data.
Thanks for your help

Get data from MySQL query for use in nodejs

Trying to query my database and each time I do, it runs all the queries at the end instead of when I need them in nodejs.
var mysql = require('mysql');
var con = mysql.createConnection({
host: database.host,
user: database.user,
password: database.password,
database: database.database
});
The connection data I am pulling from a json file.
function getSymbol(id){
var s = "";
con.query("SELECT * FROM Symbol WHERE PlayerID = '" + id + "'", function (err, result, fields) {
if (err) throw err;
console.log(result);
if (result.length < 1) {
console.log(result);
s = result[0].Symbol;
}
else {
s = "!";
}
});
console.log(s);
return s;
}
It all runs at the end of the program wondering if there is a fix or if I should switch to python (seriously considering rewriting all of it at this point).
The problem is what you have written comes under NIO and it wont wait for executing the next statement unless you ask it to. Try the below code:
async function getSymbol(id){
var s = "";
try {
let result = await con.query("SELECT * FROM Symbol WHERE PlayerID = '" + id + "'")
if (result.length < 1) {
console.log(result);
s = result[0].Symbol;
}
else {
s = "!";
}
}catch(error){
console.log(error);
throw new error;
}
console.log(s);
return s;
}
Note: I have used async/await. You can also use Promises
As mentioned, the method is NOT sync. Your result will be on the callback you pass.
con.query(sql, function (err, result) {
if (err) throw err;
console.log("The Data: " + result);
});
More Info: https://www.w3schools.com/nodejs/nodejs_mysql.asp
Moreover, you need to connect first with con.connect( <callback-here> ).
The best way to work with this is to avoid the callbacks for async/wait syntax.

Return showing undefined javascript

im writing a discord bot to check points from a database then return them. This is my code at the moment.
function userCheck(id, name) {
date = new Date().toISOString().slice(0, 19).replace('T', ' ');
con.query("SELECT id FROM users WHERE id = "+id, function (err, row) {
if (!(row && row.length) ) {
con.query("INSERT INTO `users` (id,name,rank,points,signup) VALUES ('"+id+"', "+name+", '0', '0' , '"+date+"')"), function (err, result, fields){
if (err) throw err;
}
}else{
//fine
}
});
}
function checkPoints(user){
id = user.id;
name = con.escape(user.username);
userCheck(id, name);
console.log("SELECT points FROM users WHERE id = "+id);
con.query("SELECT points FROM users WHERE id = "+id, function (err, result, fields){
return result[0].points;
});
}
My code which calls these functions is this:
return message.author.send(checkPoints(message.author));
This makes discordjs error as it is trying to return an empty message. This means my functions arent returning right. Ive look at this over and over its probably just a simple fix but I cant see it.
Thanks in advance
function checkPoints(user){ doesn't return anything i.e. same as return undefined
Since con.query is asynchronous - the simplest fix is to use a callback, like so
function checkPoints(user, cb){
id = user.id;
name = con.escape(user.username);
userCheck(id, name);
console.log("SELECT points FROM users WHERE id = "+id);
con.query("SELECT points FROM users WHERE id = "+id, function (err, result, fields){
cb(result[0].points);
});
}
checkPoints(message.author, function(result) {
message.author.send(result);
});
or, use Promise
function checkPoints(user){
return new Promise(function(resolve, reject) {
id = user.id;
name = con.escape(user.username);
userCheck(id, name);
console.log("SELECT points FROM users WHERE id = "+id);
con.query("SELECT points FROM users WHERE id = "+id, function (err, result, fields){
if(err) return reject(err);
resolve(result[0].points);
});
});
}
checkPoints(message.author)
.then(function(result) {
message.author.send(result);
});

filter[0].ID is undefined

I am making a Discord Bot add a database entry when a new user joins. To avoid duplicate entries I'm checking if the database row ID already has the members ID in it. My problem is if the member is not in the database it comes back as undefined.
var userID = member.id.toString();
var UserName = member.user.username.toString();
// var NickName = member.nickname.toString();
var DateJoined = new Date();
con.query("SELECT ID FROM listAllUsers", function (err, selectResult, fields) {
var filter = selectResult.filter(m => m.ID === userID);
console.log(filter[0].ID)
if(filter[0].ID == userID) {
console.log(`That user all ready exists in the database.`)
} else {
var sql = `INSERT INTO listAllUsers (ID, UserName, NickName, DateJoined) VALUES ('${ID}', '${UserName}', 'none', '${DateJoined}')`;
con.query(sql, function (err, result) {
if (err) throw err;
console.log(`User: ${UserName} -- ${ID} has joined the server. Added to the Database`);
});
}
});
var filter = selectResult.filter(m => m.ID === userID);
This checks if the ID is equal to any of the ID's in the database. But this is also my problem. Because if this comes back empty it will make this:
console.log(filter[0].ID) undefined. Well actually the .ID bit comes back undefined.
Well if you have an entry, than you already know the id exists....
if (filter.length > 0) {
// you have a user with the id
}
But wouldn't it make more sense to just query the user id instead of returning everyone? SELECT ID FROM listAllUsers WHERE ID=userID

Callback until for loop with query is done

I posted a question before and realized my problem actually was async functions. I managed to work out most of it, but I got one little problem left. Using async I used waterfall to create an order for the some queries...
exports.getMenu = function(id_restaurant, callback){
async.waterfall([
async.apply(firstQuery, id_restaurant),
secondQuery,
thirdQuery,
fourthQuery,
formMenu
], function(err, result){
if(err){
console.log(err);
}
callback(result);
});
};
Everything works until fourthQuery, where I have to loop to get all dishes of a menu.
function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback){
var size = array_nombresSecc.length;
var array_secciones = array_secciones;
var array_nombresSecc = array_nombresSecc;
var dishes = [];
pool.getConnection(function(err, connection) {
if(err) {
console.log(err);
callback(true);
return;
}
for (var i = 0; i < size; i++) {
connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [array_secciones[i]],
function(err, results2) {
if(err) {
console.log(err);
callback(true);
return;
}
console.log("Result query 4 " + JSON.stringify(results2));
dishes[i] = results2;
console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[i]));
// this prints the result but only if it has a value over 2
});
};
}); // pool
console.log("I'm sending " + dishes); // this logs an empty array
callback(null, dishes, array_nombresSecc);
};
So what i can see that happens from printing the value of 'i' each loop is that it always has the value of 2. Because that's 'size' value. Also, even though it's saving results of index '2' I believe the callback is being done even before the for loop is done, because my fifth function is recieving an empty array.
How can i make my code wait to callback until my for loop is done?
NOTE: Sorry, part of my code is in spanish, tried to translate the important parts of it.
There are a few ways to handle this, one is to look into promise architecture. Promise.all will let you supply one callback to handle the values from each child promise.
To use what you've already got, however, I'd push the values into your dishes array, rather than assigning them specifically to i indexes, then check the size of that array at the end of each connection. When the array length matches the size, fire the callback. (as seen below)
If you need a way to tie each result to that specific i value, I'd recommend pushing them as an object
dishes.push({'index': i, 'dish': results2})
Afterward, if you need the array of just dishes, you can sort the array by that index value and run a map function.
dishes.sort(function(a,b){ return a.index - b.index; })
dishes = dishes.map(function(a){ return a.dish })
Here's the code adjusted:
function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback) {
var size = array_nombresSecc.length;
var array_secciones = array_secciones;
var array_nombresSecc = array_nombresSecc;
var dishes = [];
pool.getConnection(function(err, connection) {
if (err) {
console.log(err);
callback(true);
return;
}
for (var i = 0; i < size; i++) {
connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [array_secciones[i]],
function(err, results2) {
if (err) {
console.log(err);
callback(true);
return;
}
console.log("Result query 4 " + JSON.stringify(results2));
dishes.push(results2)
if(dishes.length == size){
console.log("I'm sending " + dishes);
callback(null, dishes, array_nombresSecc)
}
console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[i]));
// this prints the result but only if it has a value over 2
});
};
}); // pool
;
};
Since you're already using the async, I would suggest replacing the for() loop in fourthQuery with async.each().
The updated fourthQuery would look like this:
function fourthQuery(array_totalP, array_nombresSecc, array_secciones, callback){
var size = array_nombresSecc.length;
var array_secciones = array_secciones;
var array_nombresSecc = array_nombresSecc;
var dishes = [];
pool.getConnection(function(err, connection) {
if(err) {
console.log(err);
callback(true);
return;
}
async.each(array_secciones,
function(item, itemCallback) {
// Function fun for each item in array_secciones
connection.query("SELECT name, price FROM menu_product WHERE id_seccion = ? AND active = 1", [item],
function(err, results2) {
if(err) {
console.log(err);
return itemCallback(true);
}
console.log("Result query 4 " + JSON.stringify(results2));
dishes.push(results2);
console.log("VALOR PLATILLOS EN i : " + JSON.stringify(dishes[dishes.length-1]));
// this prints the result but only if it has a value over 2
return itemCallback();
});
},
function(err) {
// Function run after all items in array are processed or an error occurs
console.log("I'm sending " + dishes); // this logs an empty array
callback(null, dishes, array_nombresSecc);
});
}); // pool
};
Alternatively, you can use async.map(), which handles gathering the results in the final callback so doesn't rely on the dishes variable.

Categories