Discord.js "cannot read properties of undefined" when trying to put event handler into a seperate file

Viewed 1037

So I have been working on a discord bot. At first, I've put every event handler into index.js, which worked perfectly well.

const { Client, Collection, Intents } = require('discord.js');
const { token } = require('./config.json');
const fs = require('fs');

const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS],
partials: ['MESSAGE', 'CHANNEL', 'REACTION'], 
});

client.commands = new Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('js'));

for (const file of commandFiles) {
    const command = require(`./commands/${file}`);
    client.commands.set(command.data.name, command);
}

client.once('ready', () => {
    console.log('Ready!');
});

client.on('interactionCreate', async interaction => {
    if (!interaction.isCommand()) return;

    const command = client.commands.get(interaction.commandName);

    if (!command) return;

    try {
        await command.execute(interaction);
    }
    catch (err) {
        console.log(err);
        await interaction.reply('There was an error while executing this command!');
    }
});

client.on('messageReactionAdd', (reaction, user) => {
    const channel = client.channels.cache.find(channel => channel.name === "test");
    let message = 874736592542105640;
    let emotes = [ "kannathinking", ""];
    let roleID = (reaction.emoji.name == emotes[0] ? "874730080486686730" : "874729987310235738")

    if (message == reaction.message.id && (emotes[0] == reaction.emoji.name || emotes[1] == reaction.emoji.name)) {
    channel.send(`${user} was given the <@&${roleID}> role`);
    }
});

client.on('messageReactionRemove', (reaction, user) => {
    const channel = client.channels.cache.find(channel => channel.name === "test");
    let message = 874736592542105640;
    let emotes = [ "kannathinking", ""];
    let roleID = (reaction.emoji.name == emotes[0] ? "874730080486686730" : "874729987310235738")

    if (message == reaction.message.id && (emotes[0] == reaction.emoji.name || emotes[1] == reaction.emoji.name)) {
    channel.send(`${user} was removed from the <@&${roleID}> role`);
    }
});

client.login(token);

Then I tried storing the event-handlers in seperate files, just like I did with the commands.

const { Client, Collection, Intents } = require('discord.js');
const { token } = require('./config.json');
const fs = require('fs');

const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS],
partials: ['MESSAGE', 'CHANNEL', 'REACTION'], 
});

client.commands = new Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('js'));
const eventFiles = fs.readdirSync('./events').filter(file => file.endsWith('.js'));

for (const file of commandFiles) {
    const command = require(`./commands/${file}`);
    client.commands.set(command.data.name, command);
}

for (const file of eventFiles) {
    const event = require(`./events/${file}`);
    if (event.once) {
        client.once(event.name, (...args) => event.execute(...args));
    } else {
        client.on(event.name, (...args) => event.execute(...args));
    }
}
client.login(token);

This however didn't work well. As I started the bot it gave me positive feedback. As soon as I tried to react to a message on my discord server however, it threw the following error:

TypeError: cannot read properties of undefined (reading 'cache')

The messageReactionAdd.js event file looks like this:

module.exports = {
    name: 'messageReactionAdd',
    execute(client, reaction, user) {
        const channel = client.channels.cache.find(channel => channel.name === "test");
        let message = 874736592542105640;
        let emotes = ["kannathinking", ""];
        let roleID = (reaction.emoji.name == emotes[0] ? "874730080486686730" : "874729987310235738")

        if (message == reaction.message.id && (emotes[0] == reaction.emoji.name || emotes[1] == reaction.emoji.name)) {
            channel.send(`${user} was given the <@&${roleID}> role`);
        }
    }
}

I tried fixing the error by requiring the client object I created in index.js, aswell as requiring "Client" from discord.js. Both didn't work and I can't figure out what is missing in the event file so that it works.

1 Answers

When requiring the event file, you never defined client therefore when you call client.channels in the event handler, it doesn't actually know what client is.

To fix this issue, when executing the function, define client before the args.
Example:

for (const file of eventFiles) {
    const event = require(`./events/${file}`);
    if (event.once) {
        client.once(event.name, (...args) => event.execute(client, ...args));
    } else {
        client.on(event.name, (...args) => event.execute(client, ...args));
    }
}
Related