'TypeError: Cannot read property 'id' of undefined of discord.js
So I'm trying to have all my events in separate files. Events like "ready" and "messageCreate" are working just fine, but I can't figure this one out. Can someone please help me?
const { MessageEmbed } = require("discord.js")
module.exports = {
name: "guildMemberAdd",
run: async (member) => {
const welcome = new MessageEmbed()
.setDescription(`
<:nezuko_peek:974066160108732517> — New friend just showed up: <@${member.user.id}>
Welcome fellow adventurer in **Cozy corner**! What brings you in these sides? <:girl_love:973968823449436190> Here, go to <#972618593294512128> to introduce yourself and talk with us in <#971800237507248158>!
`)
.setImage("https://64.media.tumblr.com/01a9f72f062feaafa60cdbf80f9ba729/tumblr_inline_orgoyznIM51sd5e91_500.gif")
.setColor("#F7DF79")
.setFooter({ text: "Thank you for joining and enjoy your stay!" })
const channel = member.guild.channels.cache.get("971800237507248158")
channel.send({ content: `<@&974343947105206382>`, embeds: [welcome] })
}
}
This event called "guildMemberAdd" should be working and execute itself when member joins the server. Here's my event handler:
const { getFiles } = require("../util/functions")
module.exports = (bot, reload) => {
const {client} = bot
let events = getFiles("./events/", ".js")
if (events.length === 0){
console.log("No events to load")
}
events.forEach((f, i) => {
if (reload)
delete require.cache[require.resolve(`../events/${f}`)]
const event = require(`../events/${f}`)
client.events.set(event.name, event)
if (!reload)
console.log (`${i + 1}. ${f} loaded`)
})
if (!reload)
initEvents(bot)
}
function triggerEventHandler(bot, event, ...args){
const {client} = bot
try {
if (client.events.has(event))
client.events.get(event).run(bot, ...args)
else
throw new Error(`Event ${event} does not exist`)
}
catch(err){
console.error(err)
}
}
function initEvents(bot) {
const {client} = bot
client.on("ready", () => {
triggerEventHandler(bot, "ready")
})
client.on("messageCreate", (message) => {
triggerEventHandler(bot, "messageCreate", message)
})
client.on("guildMemberAdd", (member) => {
triggerEventHandler(bot, "guildMemberAdd", member)
})
}
But for some reason it's not working and I got error: TypeError: Cannot read property 'id' of undefined
Solution 1:[1]
When you are calling your command, you are passing two arguments bot
and ...args
while in your exported command, it is only expecting ...args
. So you have two options: either change the order of the arguments you are passing so that it is something like this: client.events.get(event).run(...args, bot)
, or remove the bot argument as you are not using it in the command anyway. Your final code in your event handler might look something like this:
const { getFiles } = require("../util/functions");
module.exports = (bot, reload) => {
const { client } = bot;
let events = getFiles("./events/", ".js");
if (events.length === 0) {
console.log("No events to load");
}
events.forEach((f, i) => {
if (reload) delete require.cache[require.resolve(`../events/${f}`)];
const event = require(`../events/${f}`);
client.events.set(event.name, event);
if (!reload) console.log(`${i + 1}. ${f} loaded`);
});
if (!reload) initEvents(bot);
};
function triggerEventHandler(bot, event, ...args) {
const { client } = bot;
try {
if (client.events.has(event)) client.events.get(event).run(...args);
else throw new Error(`Event ${event} does not exist`);
} catch (err) {
console.error(err);
}
}
function initEvents(bot) {
const { client } = bot;
client.on("ready", () => {
triggerEventHandler(bot, "ready");
});
client.on("messageCreate", (message) => {
triggerEventHandler(bot, "messageCreate", message);
});
client.on("guildMemberAdd", (member) => {
triggerEventHandler(bot, "guildMemberAdd", member);
});
}
Solution 2:[2]
You should use listBox.SelectedItem.ToString()
instead of SelectedValue
.
So, you want to select an item from a ListBox
and display it in a TextBox
?
This is the beginner solution to the problem.
Additionally, you have to subscribe to the SelectionChanged
event of the ListBox
.
XAML:
<TextBox x:Name="textbox" />
<ListBox x:Name="listBox" SelectionChanged="ListBox_SelectionChanged"/>
Code Behind:
public partial class MainWindow : Window
{
private readonly List<string> _cities;
public MainWindow()
{
InitializeComponent();
cities = new List<string>
{
"myCity1",
"myCity2",
"myCity3",
"myCity4"
};
listBox.ItemsSource = _cities;
}
// Gets called every time the selection of the ListBox changes.
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
textbox.Text = listBox.SelectedItem.ToString();
}
}
The same effect can be achieved using data-binding.
XAML:
<TextBox x:Name="textbox" Text="{Binding SelectedCity}" />
<ListBox x:Name="listBox" SelectedItem="{Binding SelectedCity}" />
Code-behind:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private readonly List<string> _cities;
private string? _selectedCity;
public event PropertyChangedEventHandler? PropertyChanged;
public string SelectedCity
{
get => _selectedCity ??= string.Empty;
set
{
_selectedCity = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedCity)));
}
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
_cities = new List<string>
{
"myCity1",
"myCity2",
"myCity3",
"myCity4"
};
listBox.ItemsSource = _cities;
}
}
Use whichever works best for your use case.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Caladan |
Solution 2 |