filter[0].ID is undefined - javascript

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

Related

Can not insert id number using postman

This is the code in nodejs:
//Insert an employee
app.post('/employees', (req, res) => {
let emp = req.body;
var sql = "SET #EmpID = ?; SET #Name = ?; SET #EmpCode = ?; SET #Salary = ?; \
CALL EmployeeAddOrEdit(#EmpID,#Name,#EmpCode,#Salary);";
mysqlConnection.query(sql,[emp.EmpID, emp.Name, emp.EmpCode, emp.Salary],(err, rows, fields) => {
if (!err)
rows.forEach(element => {
if (element.constructor == Array)
res.send('Inserted employee id : ' + element[0].EmpID);
});
else
console.log(err);
})
});
I don't know if you will be able to see the image.
In the postman it keeps giving me this message:
Inserted employee id : null
Not getting the id number. In mysql workbench created the db with all the data proper settings, had 4 names, the delete process with postman was successful, but can't simply insert the data
You cannot return more than one response. So you can't use res.send in a loop.
But you can create an array and add all the ids to the array and present them in the response.
//Insert an employee
app.post('/employees', (req, res) => {
let emp = req.body;
var sql = "SET #EmpID = ?; SET #Name = ?; SET #EmpCode = ?; SET #Salary = ?; \
CALL EmployeeAddOrEdit(#EmpID,#Name,#EmpCode,#Salary);";
const container = []; //Create an empty array
mysqlConnection.query(sql, [emp.EmpID, emp.Name, emp.EmpCode, emp.Salary], (err, rows, fields) => {
if (!err) {
rows.forEach(element => {
if (element.constructor == Array)
container.push(row.insertedId); //Push the ids to the array
});
res.send('Inserted employee ids : ' + container.join());
}
else
console.log(err);
})
});

Functions out of order when getting results from SQL

When an existing SQL record exists I want to use it rather than adding another, but if it doesn't yet exist I want to add it. The issue I am having is that when my Node.js app's endpoint is called it's not executing in the correct order so the SQL lookup to find existing records is happening after I check it's length to see if I need to add a new record.
// it does this second
let existingGet = "SELECT * FROM Items WHERE name = '" + productName + "'";
let existingItem = async () => {
db.query(existingGet, function (err, rows, fields) {
return rows;
});
};
// it does this first
if (await existingItem().length > 0) {
// Existing found, use existing
itemId = existingItem.ID;
} else {
// Item not found, create new
var sql = "INSERT INTO Items (...) VALUES (...)";
await db.query(sql, async function (err, result) {
itemId = existingItem.affectedRows.ID;
});
}
The desired outcome is that it does the first section before the second section because the second section needs the results of the first.
Try removing the outer brackets so that the existingItem will receive the result from the query
// it does this second
let existingGet = "SELECT * FROM Items WHERE name = '" + productName + "'";
//removed outer brackets
let existingItem = async () =>
db.query(existingGet, function (err, rows, fields) {
return rows;
});
// it does this first
if (await existingItem().length > 0) {
// Existing found, use existing
itemId = existingItem.ID;
} else {
// Item not found, create new
var sql = "INSERT INTO Items (...) VALUES (...)";
await db.query(sql, async function (err, result) {
itemId = existingItem.affectedRows.ID;
});
}
Do it in a single db call using sql command
"INSERT INTO Items (...) VALUES (...)
WHERE NOT EXISTS (SELECT 1 FROM Items WHERE name = ...)"
And use sql command parameters instead of concatenation to avoid sql injection.

How to find a User ID from a Username in Discord.js?

I have a json file (localJSON.json) with Discord usernames (i.e. JohnDoe#1234) and need to get the User IDs from these usernames in order to have a role added. Every place I have looked online has resulted with either an 'undefined' or 'null' value for rMember. Verified that the code to add a role works when given a User ID as a string, but can't find how to get a User ID from a username.
How do I get a user's ID from their Username using Discord.js?
localJSON.json
[
{
"discordName": "JohnDoe#1234"
},
{
"discordName": "MarySue#5678"
}
]
function addRole(discordUsername, gameName, message){
var roleName = "";
//Switch statement to assign roleName to a valid guild role based on argument
var userID = discordUsername.id; //Pseudo code, Need to accomplish this
var rMember = message.guild.members.get(userID); //Needs UserID as string
var gRole = message.guild.roles.find((role) => role.name == roleName);
if (!rMember) { //if member not in server
message.channel.send(rMember + " is not in the server!");
} else { //assign role
rMember.addRole(gRole);
}
}
async run(message, args){
...
for (var i = 0; i < localJSON.length; i++) {
var currentEntry = localJSON[i];
var currrentUserName = currentEntry.discordName;
addRole(currrentUserName, args, message); //addRole(discordUsername, gameName, message);
}
}
You'll want to do
client.users.cache.find(u => u.tag === 'Someone#1234').id
Discord.js v12 uses .cache now, so you have to run find on the cache, and v12 also removes Collection#find(key, value) in favor of Collection#find(data => data.key === value).

Checking existing element in database with Node.js and MySQL

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

nodeJS create dynamic array and use as response

Hi i am creating an empty array then populating it with data from a mongo query using a forEach Loop.
i have been attempting this now for 4 days and nothing i seem to do is working i know im close but being a newbie to javascript and MEAN stack i just cant figure it out.
i have attached the code with comments on everything i am trying to do.
please any help would be awesome..
var mongoose = require('mongoose'),
User = require('../../models/UserModel'),
async = require('async');
module.exports.getfollowing = function(req, res){
//grab the Users ID from the body
var thefollower = req.body.follower;
//create empty array that i want to populate with the followee's ID and Avatar url
var obj = [];
//query mongo for the user
User.findOne({ _id: thefollower }, function (err, user) {
if (err) {
console.log(err);
res.json(err);
} else {
//grab the following element of the users mongo schema -- should return all the followee's ID's -- tested works
var following = user.following;
//iritate throught all the followee's
async.forEach(following, function(item, callback) {
//current followee
var user = item;
//query mongo for the followee
User.findOne({_id: user}, function(err, followee, callback){
//get followee's ID and Avatar url
var id = followee._id;
var avatar = followee.avatar;
//add the followee's ID and Avatar url to the obj array
obj.push({
id: id,
avatar: avatar
});
});
//see if this worked - returns empty
console.log(obj);
callback();
}, function(err) {
//see if this worked - returns empty
console.log(obj);
//respond to the client - returns empty
res.json(obj);
});
}
});
};
You need to move your callback(); that is at the end of your async.forEach() callback to inside the User.findOne({_id: user}, ...) callback (right after you call obj.push()) because that is when you are actually done with item. With your current code you are telling the async module immediately that you are done with item, before your mongo query has a chance to complete.
mscdex
Was spot on his answer solved my issue for future help to others here is the code
var mongoose = require('mongoose'),
User = require('../../models/UserModel'),
async = require('async');
module.exports.getfollowing = function(req, res){
//grab the Users ID from the body
var thefollower = req.body.follower;
//create empty array that i want to populate with the followee's ID and Avatar url
var obj = [];
//query mongo for the user
User.findOne({ _id: thefollower }, function (err, user) {
if (err) {
console.log(err);
res.json(err);
} else {
//grab the following element of the users mongo schema -- should return all the followee's ID's -- tested works
var following = user.following;
//iritate throught all the followee's
async.forEach(following, function(item, callback) {
//current followee
var user = item;
//query mongo for the followee
User.findOne({_id: user}, function(err, followee){
//get followee's ID and Avatar url
var id = followee._id;
var avatar = followee.avatar;
//add the followee's ID and Avatar url to the obj array
obj.push({
id: id,
avatar: avatar
});
//see if this worked - returns empty
console.log(obj);
callback();
});
}, function(err) {
//see if this worked - returns empty
console.log(obj);
//respond to the client - returns empty
res.json(obj);
});
}
});
};

Categories