I'm making a Discord bot using discord.js, and I'm starting to add JSON stuff to it, so that I can store info for individual users, in a separate file. However, I keep getting an error that says planet is not defined, at the line that says if (bot.log[mentionedGuyName].planet == undefined) {. There are some variables, modules etc. in here that haven't been declared or whatnot, but that's only because if I put all my code on here, it would be pages long. My JSON file is called log.json.
The general purpose of this code block, if it helps, is to see if the user already has a "planet". If so, the bot finds gets that value from the JSON file, and sends it to the channel. If not, then it picks a random one (code I didn't put here because of size)
I think I understand at least kind of why the error is occurring (the planet property isn't defined), but I'm not sure how to fix it. If anyone knows how to declare a JSON property or whatever is going on here, I and my server would be most grateful. Thanks in advance!
Here's my JavaScript file:
let mentionedGuy = message.mentions.members.first();
let mentionedGuyName = null;
let noMentions = message.mentions.members.first() == false ||
message.mentions.members.first() == undefined;
if (noMentions) return;
else mentionedGuyName = mentionedGuy.user.username;
if (message.content.startsWith(prefix + "planet")) {
if (message.content.length > 7) {
if (bot.log[mentionedGuyName].planet == undefined) {
bot.log[mentionedGuyName] = {
planet: jMoon
}
fs.writeFile('./log.json', JSON.stringify(bot.log, null, 4), err => {
if (err) throw err;
});
message.channel.send(targeting);
message.channel.send(coords);
} else {
message.channel.send(bot.log[mentionedGuyName].planet);
}
}
}
Change it so it checks the typeof
if(typeof <var> == 'undefined') //returns true if undefined
Noting that typeof returns a string
Source
Related
let adminMap = new Map()
async function orionCheck(interaction, adminMap) {
const guild = await client.guilds.fetch(General.SERVER.ID)
const members = await guild.members.fetch()
var memberList = [];
members.forEach(member => memberList.push(member.user.id));
for (let i = 0; i < memberList.length; i++) {
if (members.get(memberList[i]).roles.highest.permissions.has("ADMINISTRATOR")) adminMap.set(members.get(memberList[i]).user.id, {BPM: 0, KPM: 0}) //console.log(members.get(memberList[i]).user.id)
}
var orionObjects = {
banObject: ["API/Orion Objects/OrionData.json", "Ban", "BPM", adminMap.get(interaction.user.id).BPM],
kickObject: ["API/Orion Objects/Kickbject.syrex", "Kick", "KPM", adminMap.get(interaction.user.id).KPM]
}
var objectPick = orionObjects.unknown;
if (interaction.commandName == 'ping' && General.SERVER.CHANNELS.LOGS !== "") {
objectPick = orionObjects.banObject;
if (client.orion == undefined) {
client.orion = adminMap;
console.log(client.orion.get(interaction.user.id), "client.orion made")
} else {
client.orion.set(client.orion.get(interaction.user.id).BPM, client.orion.get(interaction.user.id).BPM++)
console.log(client.orion.get(interaction.user.id))
//console.log(client.orion)
}
} else return; //ping and topic cmds are used as placeholder for ban and kick
if (interaction.commandName == 'topic' && General.SERVER.CHANNELS.LOGS !== "") {
} else return;
}
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
orionCheck(interaction, adminMap);
});
this is code for every time a command is executed, it adds 1 to your specific user on a map which is what the map is there for. the client.orion is set to the map so that it remembers it each time the command is executed and makes the map globally executable. the if statement is checking if the client.orion was already made and if its undefined it makes it. pretty simple. but the problem is, for some reason on startup, you execute the command. it makes the client.orion then you execute it again and it does the else statement since now client.orion already exists and it adds one to the array. but when you execute it a third time, it stays at one as shown
https://i.imgur.com/Uve78bx.png
This isn't a solution to your particular problem (but maybe it can provide some clues on what I was referring to in comments.)
On a Map object, set takes two parameters, the key and the value.
You have this line in your else block:
client.orion.set((interaction.user.id).BPM, client.orion.get(interaction.user.id).BPM++)
Notice that the "key" is undefined because (interaction.user.id).BPM doesn't exist.
You should have this line instead:
client.orion.set(interaction.user.id, client.orion.get(interaction.user.id).BPM++)
I thought it was strange when tested your code both ways (as undefined, and as defined) and got the same results. But whats really going on is that the set() is doing no work when the key passed to it is undefined. Instead the code in the value parameter is doing work (even though set() is not):
client.orion.get(interaction.user.id).BPM++
ALSO:
Your value parameter to set() has a logical error in that it's supposed to be an object. You are passing a integer to it. You didn't encounter what unexpected results this will create because so far your set() isn't doing work due to the undefined key.
I'm making a discord.js bot that has commands that can have different parameters, such as mc!start vanilla, mc!start tekkit. Only singular string entries are allowed, as that's what I made it to do. But, if the user does not input a parameter, and just does mc!start, I want it to say that you cannot leave the parameter blank, but when I input only mc!start, the script gives me the "TypeError: Cannot read property 'toLowerCase' of undefined" error. I've been trying to do assignment functions and other things like that, but no cigar. Here is a splice of the code.
client.on('message', (message) => {
const messagearray = message.content.trim().split(' ');
const command = messagearray[0];
const minecraft_server = messagearray[1].toLowerCase();
if(command === (`${prefix}help`)) {
message.channel.send('Current Commands: !help, !start(Vanilla, Tekkit, Pixelmon, FarmingValley), !shutdown, !randomsong');
}
else if(command === (`${prefix}start`)) {
if(mcVersions.indexOf(minecraft_server) === -1) {
// more code
Check whether the array element is set before trying to call methods of it.
const minecraft_server = messagearray[1] ? messagearray[1].toLowerCase() : "";
Instead of "" at the end you could provide a default server.
I have a probleme with this part of code :
message.content = message.content.toLowerCase();
var badWords = ["some bad words"];
const rpsInsulte = ["some funny answer"]
var words = message.content.toLowerCase().trim().match(/\w+|\s+|[^\s\w]+/g);
var containsBadWord = words.some(word => { return badWords.includes(word); });
if (containsBadWord) {
if(message.member.roles.some(r=>["role1"].includes(r.name)) || message.member.roles.some(r=>["role2"].includes(r.name)) || message.member.roles.some(r=>["role3"].includes(r.name))) {
message.channel.send("My message").then(msg => {
msg.delete(10000)
});
if (message.author.bot) return;
} else {
var response = rpsInsulte[Math.floor(Math.random()*rpsInsulte .length)];
message.channel.send(response).then().catch(console.error).then(msg => {
msg.delete(10000)
});
}
}
}
Actually when an other bot delete something on discord i got this error : "TypeError: Cannot read property 'some' of null" for this part of code :
var containsBadWord = words.some(word => {
return badWords.includes(word);
});
My bot no longer works whenever a message is deleted by another bot.
There's something I can do for this issue ?
As a disclaimer, I've never used Discord.js but here's my opinion.
It seems that you know what your problem is, when a message is deleted and you try to read it, you get an error because the message is not there anymore, hence the null in the error.
If you don't care about parsing the deleted message, then I'd assume you can just check if it's null and if so, you don't check it, like below:
// Here is where you get the message, it can either be a message or null because it was deleted.
var words = message.content.toLowerCase().trim().match(/\w+|\s+|[^\s\w]+/g);
// Only use .some on it if it's not null.
// Basically if there's a message stored in words, do the following and if not, it just gets passed over.
// If you'll notice, it looks just like the lines below where you check for if (containsBadWord).
if (words) {
var containsBadWord = words.some(word => { return badWords.includes(word); });
}
Let me know if this still does not solve your problem or if you really need to check the deleted messages even, and I'll look over the Discord.js documentation some more and see what can be done.
I'm guessing I'm doing this the wrong way and should be using promises or something but I'm trying to create a CMS whereby you can edit a mongodb document which then translates into a blog post or any template with the variables filled out.
My CMS creates a list of blogs which only have the blog image, author, title, date modified, and the mongodb document _id as a data-id attribute.
When you click on 1 of the blogs it passes the blogId via socket.io to the server, the server searches for the blog, then renders the blogTemplateForm.pug file and sends that html back to the client where the client checks if there's already html in the #editor container, deletes the html and then appends the new html inside the edit container where the user can then edit it.
Now this document lookup is handled by a mongoose model, then I set res.blog to the blog returned by that lookup via the callback function, I generate some forms for use at a later date but otherwise we then use that res.blog object to generate the html we want from the blogTemplate, and then send that html to the client.
This works great but for some unknown reason the res.blog object is sometimes undefined, even when it really shouldn't be, ie. in the next function.. like what? And so the app.render() will return an error and null for the html, so I made a loop to check whether blog is defined before rendering the template. But even this doesn't work as html sometimes gets passed as null... What gives?!
Failure
Success
If you have a look at my loop checking whether res.blog is defined it really makes no sense that any undefined res.blog object is making its way through.
socket.on('edit blog', function(blogId){
var res = {};
Blog.findById(blogId, function(err, blog){
res.blog = blog
res.form = Form(blog)
}).then(function(){
res.filledForm = Bridge(res.blog, res.form).getForm()
delete res.form
if (res.blog !== (undefined & null)) {
app.render(blogTemplateFormPath,{blog: res.blog}, function(err, html){
console.log(err);
console.log(html);
socket.emit('blog form', html)
})
} else while (res.blog == (undefined | null)) {
if (res.blog !== (undefined & null)) {
app.render(blogTemplateFormPath,{blog: res.blog}, function(err, html){
console.log(err);
console.log(html);
socket.emit('blog form', html)
})
}
}
})
})
I've tried using different operands but to no avail, always returns null about 5% of the time
if (res.blog !== (undefined | null)) {
app.render(blogTemplateFormPath,{blog: res.blog}, function(err, html){
console.log(err);
console.log(html);
socket.emit('blog form', html)
})
} else while (res.blog == (undefined | null)) {
if (res.blog !== (undefined | null)) {
app.render(blogTemplateFormPath,{blog: res.blog}, function(err, html){
console.log(err);
console.log(html);
socket.emit('blog form', html)
})
}
}
Thank you for any help. The screenshots are high res 1080p x 2 so I think you'll be able to see the code.
This looks fishy:
Blog.findById(blogId, function(err, blog){
res.blog = blog
res.form = Form(blog)
}).then(function(){
...
});
You're passing a callback to findById() and are also treating it as a promise. I can imagine that this may cause all sorts of unexpected issues.
So use just one method. My suggestion would be to use the promise:
Blog.findById(blogId).then(function(blog) {
if (! blog) {
...handle "blogId not found" here...
return;
}
...
}).catch(function(err) {
...handle errors here...
});
This will remove the need for res as well.
because res.blog !== (undefined | null) is not doing what you think it is doing.
console.log( (undefined | null) ) // 0
There is no shortcut, you need to check each one.
if (res.blog !== undefined && res.blog !== null)
or do a falsely check
if (!res.blog)
I'm trying to extract two keywords from a url in this format
localhost:3000/"charactername"/"realmname"
where I want to exctract "charactername" and "realmname" and assign them to variables.
I use:
var charactername = req.url.split("/")[1];
console.log(charactername);
var realmname = req.url.split("/")[2];
console.log(realmname);
Everything works fine and dandy at first, but then it seems a request is made for a "favicon.ico", and my variables become undefined since there is a new request url. I tried solving this by encapsulating the code snippet in an if statement like this:
if(req.url !== '/favicon.ico'){
var charactername = req.url.split("/")[1];
console.log(charactername);
var realmname = req.url.split("/")[2];
console.log(realmname);
}
The console.log outputs tells me the variables are set to their correct values, it never says it is undefined so it seems to work.. However, when the next part of the code is executed:
if(charactername.length > 0){
res.writeHead(200, {'Content-Type': 'text/html'});
renderer.view("header", {}, res);
//get json from battle.net
var characterProfile = new Profile(charactername, realmname);
//on "end"
characterProfile.on("end", function(profileJSON){
//Show profile
//Store values we need
var values = {
avatarURL: profileJSON.thumbnail,
charactername: profileJSON.name,
realmname: profileJSON.realm,
level: profileJSON.level
}
//Simple response
renderer.view("profile", values, res);
renderer.view("footer", {}, res);
res.end();
});
I get an error saying cannot read property length of undefined. So it seems the variables become undefined somehow anyway. Anyone got a clue on how to solve this?
if(x === undefined){
//do something
}
This checks if the variable is undefined, however I suggest you check what is causing the error in the first place.
if(charactername && charactername.length > 0){
...