I have a script where if there is a second argument the script will run else it will run an else statement but even if there is no second argument it will always run the script
if(member && args.slice(1) !== undefined)
{
member.kick(args.slice(1).join(' ')).then(() =>{
message.channel.send("Successfully kicked " + "`" + user.tag + "`" +" for " + "**" +args.slice(1).join(' ') + "**" + " 🙂")
}).catch(err =>{
channel.message.send("An unexpected error occured. Logs were sent to the devs")
console.log(err);
return;
});
}else{
if(member){
member.kick().then(() =>{
message.channel.send("Successfullys kicked " + "`" + user.tag + "`")
console.log (args[2], args)
}).catch(err =>{
channel.message.send("An unexpected error occured. Logs were sent to the devs")
console.log(err);
return;
});
Assuming args is an array, .slice() will always return an array and never undefined. You should check for the length directly:
if (member) {
const kick = args.length > 1 ? member.kick(args.slice(1).join(' ')) : member.kick();
kick.then(() =>{
message.channel.send("Successfully kicked " + "`" + user.tag + "`" +" for " + "**" +args.slice(1).join(' ') + "**" + " 🙂")
}).catch(err =>{
channel.message.send("An unexpected error occured. Logs were sent to the devs")
console.log(err);
});
}
args.slice(1) will never be undefined. If the array args is too short, its result will be the empty array []. This is different from undefined.
Related
I want to use the return of a query to a postgresSQL database. I don't want to just print it. I want to use it in another function. The problem is that the function here returns before it is finished with executing the code.
async function create_base_config(user_id, service_id, timer_seconds) {
var ret
var line
await db_adm_conn.query(`
INSERT INTO base_config (user_id, service_id, timer_seconds)
VALUES ('` + user_id + "', '" + service_id + "', '" + timer_seconds + "') RETURNING id;", (err, result) => {
if (err) {
ret = false
line = err
console.log("line2 err : " + line)
}
else {
ret = true
line = result.rows
console.log("line2 : " + line)
// json_return = JSON.parse(result)
// console.log(result.rows)
}
});
console.log("line: " + line)
return { ret_value: ret, line_value: line };
}
To test it i inserted debug prints. The output is:
server_1 | line: undefined
server_1 | line2 : [object Object]
so I am exectuting the code after the await before the await is finished. How can i fix that, so that he first executes all the code from the await and then the rest?
you should not use a callback function as the arrow function. You should use try catch like this:
async function create_base_config(user_id, service_id, timer_seconds) {
var ret
var line
try {
line = await db_adm_conn.query(`
INSERT INTO base_config (user_id, service_id, timer_seconds)
VALUES ('` + user_id + "', '" + service_id + "', '" + timer_seconds + "') RETURNING id;")
ret = true
}
catch (err) {
ret = false
line = err
}
return { ret_value: ret, line_value: line };
}
(node:9436) UnhandledPromiseRejectionWarning: TypeError: makeUser is not a function
Hello I tried to make a command for when the person does the command automatically adds 1 line in a cfg called users.json but this gives me this error.
Again, as I was updating my bot to discord.js V12 I got an error:
TypeError: makeUser is not a function
Here is a part the code:
if (!config.servers.servidores.includes(args[4])) {
console.log(yellow + "[" + moment.tz("America/Sao_Paulo").format('HH:mm A') + "] " + red + `[DB]` + reset + ` ${msg.author.username} ` + l7yellow + `->` + lightred + ` Configuração Errada` + reset + ` Status: ` + red + `Servidor` + reset)
const metodoembed = new Discord.RichEmbed()
.setColor("#ff0000")
.setTitle("Database Editor -> Atom")
.setDescription("An `error` was identified when\nmodifying the database.")
.addField('**Type:**', '```http\n' + 'Server' + '```', true)
.addField('Solution:', 'Check the available\nservers in the database', true)
.setThumbnail(`${msg.author.displayAvatarURL}`)
.setTimestamp()
.setFooter(`${msg.author.username}`, `${msg.author.displayAvatarURL}`);
return msg.channel.send(metodoembed); }
//
function updategive(file, json) {
fs.writeFile(file, JSON.stringify(json, null, 2), "utf8", function(err) {
console.log(purple + "[" + reset + moment.tz("America/Sao_Paulo").format('HH:mm A') + purple + "] " + `[🧮] Banco de Dados atualizado.`);
});
}
if (!users[person]) {
makeUser(person);
}
users[person].attackTime = time;
users[person].concurrents = conc;
users[person].servers = servers;
users[person].expire = moment(expire).unix();
updategive("users.json", users);
return msg.channel.send(responsegive);
}
The error is occuring in this line:
if (!users[person]) {
makeUser(person);
}
Hello seems like you are using a function that is not existing. Create a function with the name makeUser and the parameter user. So it should look like this function makeUser(user) {...}.
Also if you are using discord.js v12, make sure you replace RichEmbed with MessageEmbed.
I am using knex 0.13.0 and I am trying to insert into a mysql database with the following function:
async function create(title, description) {
//trim spaces
console.log("title: " + title)
console.log("description: " + description)
title = title.trim()
description = description.trim()
createdAt = _.now()
deleted = false
console.log("Create Post: " + title + " " + description + " " + createdAt + " " + deleted)
if (title.length < 1 || title.length > 255) throw new Error('Title is not valid.')
if (description.length < 1) throw new Error('Description is not valid.')
try {
await knex('posts').insert({
title,
description,
createdAt,
deleted
})
console.log("added to db")
return true;
} catch (e) {
return "An error occured: " + e;
}
}
The last console output with Create Post: Title Description 1505062847788 falseis shown right, but nothing is happening, even after waiting
I guess it is the asynch part of the function, but what else to do in the meanwhile?
Is there a standard way to create an entry when using knex?
Appreciate your reply!
I'm using Node 6, so can't test 'await' at the moment (came in node 7) but from this post it looks like you should assign the await response to a variable. Like:
...
var awResponse; // new variable
try {
awResponse = await knex('posts').insert({
...
In detail:
async function create(title, description) {
//trim spaces
console.log("title: " + title)
console.log("description: " + description)
title = title.trim()
description = description.trim()
createdAt = _.now()
deleted = false
console.log("Create Post: " + title + " " + description + " " + createdAt + " " + deleted)
if (title.length < 1 || title.length > 255) throw new Error('Title is not valid.')
if (description.length < 1) throw new Error('Description is not valid.')
var awResponse; // new variable
try {
awResponse = await knex('posts').insert({
title,
description,
createdAt,
deleted
})
console.log("added to db")
return true;
} catch (e) {
return "An error occured: " + e;
}
}
What you have should work just fine, but what I've been doing (as an alternative for you) is just directly using promises, and constructing my data access functions generally as follows:
function create(title, description) {
return Promise.resolve().then(function () {
// This first section is for preping the record for insert.
//
//trim spaces
console.log("title: " + title)
console.log("description: " + description)
title = title.trim()
description = description.trim()
// createdAt = _.now() // I have a error that "_" is not valid
createdAt = (new Date()).toISOString();
deleted = false
console.log("Create Post: " + title + " " + description + " " + createdAt + " " + deleted)
if (title.length < 1 || title.length > 255) throw new Error('Title is not valid.')
if (description.length < 1) throw new Error('Description is not valid.')
return { "title": title,
"description": description,
"createdAt": createdAt,
"deleted": deleted };
})
.then(function (recordToInsert) {
// This second section is for the insert.
//
console.log("Part #2");
return knex('posts').insert(recordToInsert)
.on('query-error', function(ex, obj) {
// console.log("KNEX query-error ex:", ex);
// console.log("KNEX query-error obj:", obj);
// Below logs db errors into my custom encapsulation of winston logging.
// ... and the .catch further down will still be executed.
log.logMsg('error', "DBA.INS88", "KNEX create.on.query-error", {"fnc": "create", "obj":obj, "ex":ex} );
})
})
.then(function (insertResult) {
// This third section is for post-processing the result (if needed).
//
console.log("Part #3 added to db :", insertResult);
return insertResult; // returns id value from insert;
})
.catch(function (e) {
// I omit this .catch to let the caller know about and handle the exceptions
console.log( "An error occured: " + e);
});
};
Hope this helps!
I have an array of items:
var myArr = ['item1', 'item2', 'item3'];
I'm attempting to loop over these items and check if they exist in my database. If the item does not exist, then I add it to the database.
var sql = 'Select * from DB where item="' + myArr[i] + '"';
connection.query(sql, function(e, r, f) {
if(!e && r.length <= 0) {
performInsertOnDB(myArr[i]);
}
});
My trouble is, the reference to variable i will not stay as connnection.query is asynchronous. I need to wait until the first select finishes before I can continue. I'm trying to use the Async library to accomplish this, but I must not be fully grasping how to perform the task.
This is what I have so far:
async.each(lootArray, function(lootItem, addLootItem) {
var sql = "SELECT * FROM loot_history WHERE date = DATE('" + moment(lootItem[1]).format('YYYY-MM-DD') + "') AND time = '" + lootItem[2] + "' AND itemId = " + lootItem[4];
connection.query(sql, function(error, results, fields) {
if (error) {
sendDiscordMessage(loachannel, error + ', <#105094681141977088>');
return false;
} else {
if (results.length > 0) {
//duplicates.push(lootArray[i]);
} else {
addLootItem(lootItem);
}
}
});
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if (err) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
function addLootItem(lootItem) {
var sql = "INSERT INTO loot_history SET player = " + lootItem[0] + ", date = " + moment(lootItem[1]).format('YYYY-MM-DD') + ", time = '" + lootItem[2] + ", item = " + lootItem[3] + ", itemId = " + lootItem[4] + ", itemString=" + lootItem[5] + ", response= " + lootItem[6] + ", votes= " + lootItem[7] + ", class= " + lootItem[8] + ", instance=" + lootItem[9] + ", boss=" + lootItem[10] + ", gear1=" + lootItem[11] + ", gear2=" + lootItem[12] + ", reasponseId=" + lootItem[13] + ", isAwardReason=" + lootItem[14];
connection.query(sql, function(error, results, fields) {
if (error) {
sendDiscordMessage(loachannel, error + ', <#105094681141977088>');
}
});
}
EDIT: Everything works, except the callback AddLootItem is not firing. Why is this callback not getting called? I can set log events in that if statement that execute, but the function itself never fires.
The problem is that the name of async callback is the same as the function you want to be called when the item does not exist. Try to change the name in the function to something else let's say: callback, and call it in your if statement or pass it to addLootItem, and call it there once the item added.
async.each(lootArray, function(lootItem, callback) {
var sql = "SELECT * FROM loot_history WHERE date = DATE('" + moment(lootItem[1]).format('YYYY-MM-DD') + "') AND time = '" + lootItem[2] + "' AND itemId = " + lootItem[4];
connection.query(sql, function(error, results, fields) {
if (error) {
sendDiscordMessage(loachannel, error + ', <#105094681141977088>');
calback(err);
} else {
if (results.length > 0) {
//duplicates.push(lootArray[i]);
callback();
} else {
addLootItem(lootItem, callback);
}
}
});
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if (err) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
function addLootItem(lootItem, done) {
var sql = "INSERT INTO loot_history SET player = " + lootItem[0] + ", date = " + moment(lootItem[1]).format('YYYY-MM-DD') + ", time = '" + lootItem[2] + ", item = " + lootItem[3] + ", itemId = " + lootItem[4] + ", itemString=" + lootItem[5] + ", response= " + lootItem[6] + ", votes= " + lootItem[7] + ", class= " + lootItem[8] + ", instance=" + lootItem[9] + ", boss=" + lootItem[10] + ", gear1=" + lootItem[11] + ", gear2=" + lootItem[12] + ", reasponseId=" + lootItem[13] + ", isAwardReason=" + lootItem[14];
connection.query(sql, function(error, results, fields) {
if (error) {
sendDiscordMessage(loachannel, error + ', <#105094681141977088>');
}
done();
});
}
bot.addListener('message', function (from, channel, message) {
IRClog.write("[" + (new Date()).toJSON() + "] [" + channel + "] <" + from + ">" + message + "\n");
// ============= PLAYER COMMANDS ============= //
if (logMessages){
util.log("[" + channel + "] <" + from + ">" + message);
}
console.log(message)// the message is logged
bot.whois(from,function(WHOIS){
if(typeof WHOIS.account == 'undefined'){
var isAuthed = false;
} else {
var isAuthed = true;
}
if (message.indexOf("!") === 0){//now the message is undefined
...
As described in the code, the var message is a string, and then, I don't know why, it becomes an undefined variable. Why is that happening? I didn't assign it to another value.
Depending on the execution context the function that the bot.whois executes may not have message defined in scope. You can use a closure to ensure the scope by passing in the message.
(function (msg) {
console.log(msg)// the message is logged
bot.whois(from, function(WHOIS){
var isAuthed = typeof WHOIS.account !== 'undefined';
if (msg.indexOf("!") === 0) {
...
}
})(message);
Your code is incomplete, obviously, and the actual bug probably resides somewhere below your cutoff point as you've put in your question:
bot.addListener('message', function (from, channel, message) {
IRClog.write("[" + (new Date()).toJSON() + "] [" + channel + "] <" + from + ">" + message + "\n");
// ============= PLAYER COMMANDS ============= //
if (logMessages){
util.log("[" + channel + "] <" + from + ">" + message);
}
console.log(message)// the message is logged
bot.whois(from,function(WHOIS){
if(typeof WHOIS.account == 'undefined'){
var isAuthed = false;
} else {
var isAuthed = true;
}
if (message.indexOf("!") === 0){//now the message is undefined
...
}); // end of the whois block, which is asynchronous
/* somewhere down here, message probably gets set to undefined
like this:
message = undefined; // this would run before bot.whois(from, cb); finishes
*/
}); // end of addListener
You either need to make sure that you're not messing with the message below your whois call, or you need to create a copy that you don't mess with, or you need to follow #Romoku's advice and wrap your whois call in a properly formatted closure (like the following) and pass message in to a strictly local scope:
bot.addListener('message', function (from, channel, message) {
IRClog.write("[" + (new Date()).toJSON() + "] [" + channel + "] <" + from + ">" + message + "\n");
// ============= PLAYER COMMANDS ============= //
if (logMessages){
util.log("[" + channel + "] <" + from + ">" + message);
}
console.log(message)// the message is logged
(function (msg) {
bot.whois(from,function(WHOIS){
if(typeof WHOIS.account == 'undefined'){
var isAuthed = false;
} else {
var isAuthed = true;
}
if (msg.indexOf("!") === 0){//now the message is undefined
...
}); // end of the whois block, which is asynchronous
})(message);
/* now you can do whatever you want to the message variable and bot.whois will
be able to operate on its independent, unmolested copy
*/
}); // end of addListener
Please note how in my example, and #Romoku's, message has been explicitly renamed (to msg and m, respectively), to make it clear that you're working with in a different scope with a different copy of the data.