Search code examples
javascriptnode.jsdiscorddiscord.jsbots

How to send 2 select menus in discord.js v14


I am new to discord.js v14. I used to use v13 but now there is a problem with v14 I can't handle.

This is my code:

const { SlashCommandBuilder, EmbedBuilder , ButtonBuilder , ActionRowBuilder , SelectMenuBuilder} = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('bus-test')
    .setDescription('Just testing')
    .addAttachmentOption(option => option.setName('screenshot').setDescription('Upload a screenshot').setRequired(true))
    .addStringOption(option => option.setName('other_drivers').setDescription('Enter all drivers with @').setRequired(true))
    .addStringOption(option => option.setName('passengers').setDescription('Enter all passengers with @').setRequired(true)),
  async execute(interaction) {
    const author = interaction.user;
    const drivers = interaction.options.getString('other_drivers');
    const passengers = interaction.options.getString('passengers');
    const attachment = interaction.options.getAttachment('screenshot');
    const passengersWithDots = passengers.split(' ').map(passengers => `• ${passengers}`).join('\n');
    const driversWithDots = drivers.split(' ').map(driver => `• ${driver}`).join('\n');
    const driversWithMention = `• ${author}\n${driversWithDots}`;

    const embed = new EmbedBuilder()
      .setTitle('**Report System Rules**')
      .setColor('Yellow')
      .setDescription(`${driversWithMention}\n\nPassenger(s)\n${passengersWithDots}`)
      .setImage(attachment.url);

    const selectMenu1 = new SelectMenuBuilder()
      .setCustomId('select_menu1')
      .setPlaceholder('Select an option')
      .addOptions([
        {
          label: 'Option 1',
          value: 'option_1',
        },
        {
          label: 'Option 2',
          value: 'option_2',
        },
      ]);

    const selectMenu2 = new SelectMenuBuilder()
      .setCustomId('select_menu2')
      .setPlaceholder('Select another option')
      .addOptions([
        {
          label: 'Option A',
          value: 'option_a',
        },
        {
          label: 'Option B',
          value: 'option_b',
        },
      ]);

    const button1 = new ButtonBuilder()
      .setCustomId('button1')
      .setLabel('Button 1')
      .setStyle('Primary');

    const button2 = new ButtonBuilder()
      .setCustomId('button2')
      .setLabel('Button 2')
      .setStyle('Danger');

    const row1 = new ActionRowBuilder()
      .addComponents(selectMenu1, selectMenu2);

    const row2 = new ActionRowBuilder()
      .addComponents(button1, button2);

    await interaction.reply({
      embeds: [embed],
      ephemeral: true,
      components: [row1, row2],
    });
  },
};

Here I tried to add the select menus to the action row and then send it but it gives me some error.

The error message:

data.components[0].components[1][COMPONENT_LAYOUT_WIDTH_EXCEEDED]: The specified component exceeds the maximum width
    at handleErrors (C:\Users\abodah\Desktop\shawarma\node_modules\@discordjs\rest\dist\index.js:640:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async BurstHandler.runRequest (C:\Users\abodah\Desktop\shawarma\node_modules\@discordjs\rest\dist\index.js:736:23)
    at async REST.request (C:\Users\abodah\Desktop\shawarma\node_modules\@discordjs\rest\dist\index.js:1387:22)
    at async ChatInputCommandInteraction.reply (C:\Users\abodah\Desktop\shawarma\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:111:5)
    at async Object.execute (C:\Users\x\Desktop\shawarma\commands\bus.js:69:5)
    at async Client.<anonymous> (C:\Users\x\Desktop\shawarma\bot.js:76:5) {
  requestBody: { files: [], json: { type: 4, data: [Object] } },
  rawError: {
    message: 'Invalid Form Body',
    code: 50035,
    errors: { data: [Object] }
  },
  code: 50035,
  status: 400,
  method: 'POST',

Can someone help me and explain it to me, please?

I want to send the embed menu and then add 2 select menus to it and 2 buttons.


Solution

  • There is no way to add more than one select menu in an action row. If you have more than one select menu, each one will need its own action row. This is a limitation of the Discord API.

    Another similar rule is that an action row containing a select menu cannot also contain buttons.

    What you can do is send them in different action rows:

    const row1 = new ActionRowBuilder().addComponents(selectMenu1);
    const row2 = new ActionRowBuilder().addComponents(selectMenu2);
    const row3 = new ActionRowBuilder().addComponents(button1, button2);
    
    await interaction.reply({
      embeds: [embed],
      ephemeral: true,
      components: [row1, row2, row3],
    });