How to fix cannot ready property of undefined - javascript

So, i've been coding a discord bot, and i'm getting this error when trying to check if "mrole" has the property "app". I have no idea why this is not working.
I want it to read the team's id so i can sort out the json file like this:
let barney = message.guild.roles.find(r => r.name === "Barney")
let deadpool = message.guild.roles.find(r => r.name === "Deadpool")
let hulk = message.guild.roles.find(r => r.name === "Hulk")
let mario = message.guild.roles.find(r => r.name === "Mario")
let spiderman = message.guild.roles.find(r => r.name === "Spider-Man")
let umbreon = message.guild.roles.find(r => r.name === "Umbreon")
let app = message.guild.member(message.mentions.users.first());
let app2 = message.mentions.users.first().username
var mrole
if (app.roles.has(barney.id)){
mrole = barney.id
}
else if (app.roles.has(deadpool.id)){
mrole = deadpool.id
}
else if (app.roles.has(hulk.id)){
mrole = hulk.id
}
else if (app.roles.has(mario.id)){
mrole = mario.id
}
else if (app.roles.has(spiderman.id)){
mrole = spiderman.id
}
else if (app.roles.has(umbreon.id)){
mrole = umbreon.id
}
if(mrole = barney.id || deadpool.id || hulk.id || mario.id || spiderman.id || umbreon.id){
if (client.memberspoints.mrole[app.id].name != app2){
client.memberspoints [mrole] = {
[app2.id]: {
name: `${app2}`,
mpoints: `${+args[1]}`
}
}
message.channel.send(`${app} agora tem ${+args[1]} pontos`);
}
else{
let _mpoints = client.memberspoints.mrole[app.id].mpoints
var smpoints = +_mpoints + +args[1]
client.memberspoints [mrole] = {
[app.id]:{
name: `${app2}`,
mpoints: `${smpoints}`
}
}
message.channel.send(`${app} agora tem ${smpoints} pontos`);
}
fs.writeFile ('./memberspoints.json', JSON.stringify (client.memberspoints, null, 2), err => {
if (err) throw err;
console.log('Salvo');
});
Here is the error i'm geting:
if (client.memberspoints.mrole[app.id].name != app2){
^
TypeError: Cannot read property 'app.id' of undefined
I basically want it to check if the "mrole" already has the name of the person on it, so i an sort it out by team and by name. Any ideas?

To check if an object has a certain property, you should use the object.hasOwnProperty method:
The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
so, it would go like this:
if(mrole.hasOwnProperty('app')) { // do stuff }
I recently learned that in this could potentially be a security problem, so its better to use it like this: if( Object.prototype.hasOwnProperty.call(mrole, 'app'). ( you can read more here ).
now, the probelm might be something else entirely- I noticed that in the line
if(mrole = barney.id || deadpool.id || hulk.id || mario.id || spiderman.id || umbreon.id), you ASSIGN to the mrole, and not comparing! should be if(mrole == ...

Related

How to return a value from nested javascript function?

window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};
pc.createDataChannel("");
pc.createOffer(pc.setLocalDescription.bind(pc), noop);
pc.onicecandidate = function(ice){
if(!ice || !ice.candidate || !ice.candidate.candidate) return;
ice.candidate.candidate.split('\r\n').forEach(function (line) {
if (line.indexOf("candidate")!==-1) {
var parts = line.split(' '),
addr = parts[4],
type = parts[7];
if (type === 'host') {
console.log(addr);
return addr;
}
}
});
pc.onicecandidate = noop;
};
In the above javascript, the console.log(addr) works but not the return. Please point me where I am doing wrong. I tried to wrap this in a function and that doesn't work it either.
pc.onicecandidate = function(ice){
if(!ice || !ice.candidate || !ice.candidate.candidate) return;
const hosts = [];
ice.candidate.candidate.split('\r\n').forEach(function (line) {
if (line.indexOf("candidate")!==-1) {
var parts = line.split(' '),
addr = parts[4],
type = parts[7];
if (type === 'host') {
console.log(addr);
hosts.push(addr)
}
}
});
pc.onicecandidate = noop;
return hosts;
};
Is something like that what you are after?
You want to return each host address?
This stores the hosts locally. Foreach is synchronous so when it has completed working on the collection then your function will reach the return statement.
If you want to find the first address then you might want to use .find instead of .forEach, or check that a value exists and bail from the forEach when it does (note that you're still calling that function on each item, it'll just return straight away). You can break out of a forEach but its not idiomatic, you'd have to throw an exception and you try..catch, a bit nasty in JS and not really the intended use for the syntax.
pc.onicecandidate = function(ice){
if(!ice || !ice.candidate || !ice.candidate.candidate) return;
const line = ice.candidate.candidate.split('\r\n').find(function (line) {
if (line.indexOf("candidate")!==-1) {
var parts = line.split(' ');
var type = parts[7];
return type === 'host'
}
});
pc.onicecandidate = noop;
return line.split(' ')[4]
};
Something like this I think should work for .find.
.find will return the item, which you can then pull the addr from. Alternatively you could let addr outside, update that inside, then ignore the return value from .find.
Oh, you'll want to add something if your .find returns nothing, or things will break when you try to split it and pull something out.
As long as your code in synchronous, you can write variables outside of the immediate function scope like so:
let result = null;
ice.candidate.candidate.split('\r\n').forEach(function (line) {
if (line.indexOf("candidate")!==-1) {
var parts = line.split(' '),
addr = parts[4],
type = parts[7];
if (type === 'host') {
console.log(addr);
// Save value
result = addr;
}
}
});
// ...
console.log(result);
This can be further improved by using a for (let .. of ..) loop and break to stop the loop after finding the value you're looking for.
You should also consider Array.prototype.find() for this.

TypeError: Cannot read property 'guild' of undefined I'm writing a welcome code but I keep getting that error

const db = require('quick.db')
const Discord = require('discord.js')
module.exports = (client) => {
client.on('guildMemberAdd', (member, message) => {
let welcomechannel = db.get(`welcome_${message.guild.id}`)
let welcomemsg = db.get(`Welcomemsg_${message.guild.id}`)
if(welcomechannel = null || undefined) return
if(welcomemsg = null || undefined) welcomemsg = `Hey <#${member.id}>! Make sure to read the rules and have a great time!`
let embed = new Discord.MessageEmbed()
.setColor('GOLD')
.setDescription(welcomemsg)
welcomechannel.send(embed)
})
}
The guildMemberAdd event is emitted only with a member parameter.
You have to access the guild property from the member object.
let welcomechannel = db.get(`welcome_${member.guild.id}`)
let welcomemsg = db.get(`Welcomemsg_${member.guild.id}`)
There are a couple more issues in your code. = is the assignment operator in JS. You want to use == or === (strict equality) for comparisons. And your condition to check for multiple values isn't right.
if (!welcomechannel === null || welcomechannel === undefined) {
return
}
Or better
if(!welcomechannel) {
return
}
Similarly, you can fix the welcomemsg condition with the following.
if(!welcomemsg) {
welcomemsg = `Hey <#${member.id}>! Make sure to read the rules and have a great time!`
}
Or better
const DEFAULT_MESSAGE = `Hey <#${member.id}>! Make sure to read the rules and have a great time!`
const welcomemsg = db.get(`Welcomemsg_${guildId}`) || DEFAULT_MESSAGE
Here's the fixed code.
client.on('guildMemberAdd', (member) => {
const { id: guildId } = member.guild
const welcomechannel = db.get(`welcome_${guildId}`)
const DEFAULT_MESSAGE = `Hey <#${member.id}>! Make sure to read the rules and have a great time!`
const welcomemsg = db.get(`Welcomemsg_${guildId}`) || DEFAULT_MESSAGE
if (!welcomechannel) {
return
}
// rest of the code
})

Receiving error message when initialising JavaScript function

So below is my javascript code. It's wrapped in module.exports, but that's not the error.
parseMention = (arg, asId = false) => {
if(!arg.startsWith('<#') && arg.endsWith('>')) return undefined
let id = arg.slice(2, -1)
if(id.startsWith('!')) id.slice(1)
if(asId === true) return id
if(asId === false) return bot.users.cache.get(id)
}
despite it seeming correct to me, I get the following error message:
SyntaxError: Invalid shorthand property initializer
Any help would be much appreciated
It's wrapped in module.exports, but that's not the error.
I'm pretty sure there is the error.
This part of your code won't throw a SyntaxError: Invalid shorthand property initializer error. It would be great to see your module.exports, but it's 99.9% that you're trying to export an object like this and the = after parseMention is an invalid shorthand property initialiser:
// This is invalid syntax
module.exports = {
parseMention = (arg, asId = false) => {
if (!arg.startsWith('<#') && arg.endsWith('>')) return undefined;
let id = arg.slice(2, -1);
if (id.startsWith('!')) id.slice(1);
if (asId === true) return id;
if (asId === false) return bot.users.cache.get(id);
}
}
This should work:
module.exports = {
parseMention(arg, asId = false) {
if (!arg.startsWith('<#') && arg.endsWith('>')) return undefined;
let id = arg.slice(2, -1);
// it won't do anything, slice won't mutate id and you don't return
if (id.startsWith('!')) id.slice(1);
if (asId === true) return id;
if (asId === false) return bot.users.cache.get(id);
},
};

Can't read property 'name' of undefined

I've been getting an error along the lines of "Cannot read property 'name' of undefined" and the error traces back to this code
const roleName = message.guild.roles.cache.find(r => (r.name === args[1].toString()) || (r.id === args[1].toString().replace(/[^\w\s]/gi, '')));
What's going wrong here?
slightly larger peice of code
if (!message.member.hasPermission('MANAGE_ROLES')) return message.channel.send(`You do not have MANAGE_ROLES permission`)
try {
const user = message.mentions.users.first();
const member = message.guild.member(user);
const roleName = message.guild.roles.cache.find(r => (r.name === args[1].toString()) || (r.id === args[1].toString().replace(/[^\w\s]/gi, '')));
//after this i create a discord embed, give the member the role specified then send the embed.
} catch (err) {
console.log(err)
}
Add an Elvis operator:
const roleName = message.guild.roles.cache.find(r =>
(r?.name === args[1].toString())
|| (r?.id === args[1].toString().replace(/[^\w\s]/gi, ''))
);
Or do it the old way:
const roleName = message.guild.roles.cache.find(r =>
r
&& (r.name === args[1].toString())
|| (r.id === args[1].toString().replace(/[^\w\s]/gi, ''))
);
So you're getting this error because you're trying to access 'r.name' in your Array.find() method and some of the entries in the array appear to be 'undefined' or 'null'. I would first run an Array.filter(r => !!r) and then chain on the .find() method afterwards to make sure all your entries are not undefined/null.

how to fix this TypeError: Cannot read property 'name' of null

how to fix this error
music.on('voiceStateUpdate',(lama, baru) => {
var state = null;
let Role = baru.roles.find((r) => ["IRON", "BRONZE"].includes(r.name));
const kategorikanal = '700743802574602260'
const channelid = '700743824346972231'
if(!lama.voiceChannel && !baru.voiceChannel) return;
if(!lama.voiceChannel && baru.voiceChannel) {state = "join"}
else if(lama.voiceChannel && !baru.voiceChannel) {state = "leave"}
else if(lama.voiceChannel.id !== baru.voiceChannel.id) {state = "move"}
else if(lama.voiceChannel.id == baru.voiceChannel.id) return;
console.log(state);
//!baru.member.roles.has(allowedRole)
if(baru.voiceChannelID === channelid || !baru.voiceChannelID === Role || Role !== null && Role !== '') {
console.log(baru.displayName + ' gabisabgo hrus ada rank ranked ');
// const Role = baru.guild.roles.get("724997095236304987");
baru.guild
.createChannel(`${Role.name} | ${baru.user.username}`,"voice")
.then(tempChannel => {
tempChannel.overwritePermissions(baru.guild.defaultRole.id, {
CONNECT: false,
})
tempChannel.overwritePermissions(Role.id, {
CONNECT: true
})
tempChannel.setParent(kategorikanal);
baru.setVoiceChannel(tempChannel.id);
tempChannel.setUserLimit("5");
})
.catch(console.error)
}
if(lama.voiceChannelID || !lama.voiceChannelID === Role || Role !== null && Role !== '') {
console.log(lama.displayName + ' gabisabgo hrus ada rank ranked ');
const voicelama = lama.guild.channels.get(lama.voiceChannelID);
let Role = baru.roles.find((r) => ["IRON", "BRONZE"].includes(r.name));
if(voicelama.name.startsWith(`${Role.name} | ${baru.user.username}`)){
let sawadikap = `**${baru.user.username}'s**` + " **Team**"
var koko = new Discord.RichEmbed()
.setColor("#FF4654")
.setThumbnail(`${baru.user.avatarURL}`)
.addField('**Good Game Well Played**',`${sawadikap}`)
.setFooter("#Valorant Indonesia Community." , 'https://i.imgur.com/yPWqxxu.png')
voicelama.delete()
.then(function() {
music.channels.get('725080861392896101').send(koko)
})
.catch(console.error);
}
}
})
ERROR VIEW
.createChannel(${Role.name} | ${baru.user.username},"voice")
^ TypeError: Cannot read property 'name' of null
Have you stepped through the code in debug mode? I recommend setting breakpoints, creating watches, and checking the value of the variables as you step through. If you don't feel comfortable doing so, can you please put in the following, and tell me what the console logs? :
console.log(Role)
console.log(Role.name)
Although Role is not null, The value of Role.name is null, meaning that it has no value assigned to it. That issue occurs here:
let Role = baru.roles.find((r) => ["IRON", "BRONZE"].includes(r.name));
So I see two possibilities:
No roles contain those names.
I thought that find should only result one result, but I can't seem to find good documentation of that method. Is it possible that both roles are found and a collection is returned? This would mean that there would be a collection of multiple roles, meaning that Role would not contain the data members that a Role object type would. This means that you would have to index one of the roles before using the name.
//
//if there isn't a matching role, then terminate the method.
if (Role == null)
{
return;
}
//if there are multiple roles that match the criterion, just use the first one.
//The alternative is that we could make it into a loop that handles it for all of them.
else if (Role instanceof Array)
{
if (Role.length == 0)
{
return;
}
Role = Role[0]
}
Add the above lines before calling baru.guild.createChannel.

Categories

Resources