简体   繁体   中英

Discord.js, Cannot read properties of undefined (reading 'edit')

I am creating SlashCommands for my Discord bot, now I am working with buttons and got stuck with "Cannot read properties of Undefined" error

Below is the code for RPS command:

const {
  MessageEmbed,
  MessageActionRow,
  MessageButton,
  Message,
} = require("discord.js");

module.exports = {
  data: new SlashCommandBuilder()
    .setName("rps")
    .setDescription("Rock Paper Scissors"),

  async execute(interaction) {
    let hand = [
      {
        txt: "Rock",
        emoji: "✊",
        index: 0,
      },
      {
        txt: "Paper",
        emoji: "✋",
        index: 1,
      },
      {
        txt: "Scissors",
        emoji: "✌",
        index: 2,
      },
    ];

    let botMove = hand[Math.floor(Math.random() * 3)];

    const rpsMsg = await interaction.reply({
      embeds: [
        new MessageEmbed() // embed
          .setColor("GREEN")
          .setTitle("RockPaperScissors")
          .setDescription("Choose a handsign!"),
        /*.setImage("") // Provide the source of Image*/
      ],
      components: [
        // components
        new MessageActionRow().addComponents(
          new MessageButton() // making Rock button
            .setCustomId("rps_rock") //set the custom id to the rock
            .setLabel("✊ Rock")
            .setStyle("PRIMARY"), // there are different styles of buttons you can use
          new MessageButton() // making Paper button
            .setCustomId("rps_paper") // set the custom id for Paper
            .setLabel("✋ Paper")
            .setStyle("PRIMARY"),
          new MessageButton() // making Scissors button
            .setCustomId("rps_scissors") // making Scissors button
            .setLabel("✌ Scissors")
            .setStyle("PRIMARY")
        ),
      ],
      fetchyReply: true, //we will edit  the message later
    });

    // define variables
    let win = 0; // 0 is Loss, 1 is Tie, 2 is Win
    let userMove;

    const filter = (interaction) => !interaction.user.bot; // filter out bots
    const collector = interaction.channel.createMessageComponentCollector({
      // create a message component collector with some options below
      filter, // apply the filter defined above
      componentType: "BUTTON", // button collector
      time: 10000, // im ms = 10 seconds
    });
    collector.on("collect", async (i) => {
      if (!i.isButton()) return; //if collected is not button then return

      if (i.customId.startsWith("rps")) {
        await i.deferUpdate(); //deffering the interaction so it will not load so long
        let move = i.customId.split("_")[1]; // split the button custom ID to 2 parts (it will split in the _), and define the hand sign which is rock, paper and scissors as the variable
        userMove = hand.find((v) => v.txt.toLowerCase() == move); // find the object which name property equals to the move variable, which is rock, paper and scissors, from the hand array defined above

        switch (
          move // a switch statement
        ) {
          case "rock":
            win = botMove.index == 0 ? 1 : botMove.index == 1 ? 0 : 2;
            break;
          case "paper":
            win = botMove.index == 0 ? 2 : botMove.index == 1 ? 1 : 0;
            break;
          case "scissors":
            win = botMove.index == 0 ? 0 : botMove.index == 1 ? 2 : 1;
            break;
        }

        let embed = rpsMsg.embeds[0]; // get the embed that sent before
        // edit the embed
        embed.color = "BLUE";
        embed.description = `I choose ${botMove.txt}! ${
          win == 0 ? "You lost!" : win == 1 ? "We tied!" : "You win!"
        } (${userMove.emoji} ${win == 0 ? "<" : win == 1 ? "=" : ">"} ${
          botMove.emoji
        })`;

        let components = rpsMsg.components; // get the components which are buttons that sent before
        // Disabling all buttons
        components[0].components.forEach((comp) => {
          if (comp.customId == i.customId) {
            comp.disabled = true; // disable the button
            comp.style = "SECONDARY"; // change the style of the button, color is gray
          } else comp.disabled = true;
        });

        // edit the message
        await rpsMsg.edit({
          embeds: [embed],
          components: components,
          fetchyReply: true,
        });
        collector.stop(); // stop the message component collector
      }
    });
  },
};

However, when I set the values for 'embed' and components directly:

let embed = /*rpsMsg.embeds[0];*/ new MessageEmbed() // embed
          .setColor("GREEN")
          .setTitle("RockPaperScissors")
          .setDescription("Choose a handsign!");

                             ...

let components = /*rpsMsg.components;*/ [
          new MessageActionRow().addComponents(
            new MessageButton() // making Rock button
              .setCustomId("rps_rock") //set the custom id to the rock
              .setLabel("✊ Rock")
              .setStyle("PRIMARY"), // there are different styles of buttons you can use
            new MessageButton() // making Paper button
              .setCustomId("rps_paper") // set the custom id for Paper
              .setLabel("✋ Paper")
              .setStyle("PRIMARY"),
            new MessageButton() // making Scissors button
              .setCustomId("rps_scissors") // making Scissors button
              .setLabel("✌ Scissors")
              .setStyle("PRIMARY")
          ),
        ];

the problem seems to be gone, and the only problem left is with the last method:

await rpsMsg.edit({
          embeds: [embed],
          components: components,
          fetchyReply: true,
        });

Now it's "Cannot read properties of undefined (reading 'edit')"

How can I provide proper access to the poperties?

fetchyReply needs to be fetchReply .

Your Code:

await rpsMsg.edit({
  embeds: [embed],
  components: components,
  fetchyReply: true,
});

Edited Code:

await rpsMsg.edit({
  embeds: [embed],
  components: components,
  fetchReply: true,
});

I hope it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM