Isolating interactions on Select Menu’s

Hello friends! Looking for some guidance and did not get too far online Setup: I have a Select Menu and a Button in a global channel that users can interact with When the user selects an option, it is stored to a variable. The button is used to “confirm” the selection (UX 🤷‍♂️) Code for posting the embed is in our Bot OnReady event Code for handling is in a separate InteractionCreate event handler Issue: All works except when another user interacts with the Select Menu, it effects the choice for a different user when they click confirm. My assumptions: I am trying to use a Component Collector with filter, however, adding this to the interactioncreate seems to only create a collector after the user has already interacted Or, does it make sense to create a map with discordID: selected option and look for this on button click? I can post code and screenshots if needed for better context. TIA 👌
3 Replies
d.js toolkit
d.js toolkit3y ago
• What's your exact discord.js npm list discord.js and node node -v version? • Post the full error stack trace, not just the top part! • Show your code! • Explain what exactly your issue is. • Not a discord.js issue? Check out #useful-servers.
treble/luna
treble/luna3y ago
You have to attach it to the message that contains the components
CRYSTAL
CRYSTALOP3y ago
Does that also include each reply with new components? For anyone who might stumble on this thread, I managed to get this working as below (now, other use interactions do not disrupt selections). Note: I will leave this open temporarily in-case there is some bad practice here or something that could be better handled: Summary: 1. I have nested component collectors for each reply with new components 2. Instead of saving selected value to a global variable on Select Menu click, I am accessing the map of the collector to get the Select Menu selection embedHandler.js
module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {


if(interaction.type == InteractionType.MessageComponent) {
if(interaction.customId == 'view-shop') {

const packs = await Packs.find();
const select = new StringSelectMenuBuilder()
.setCustomId('cards')
.setPlaceholder('Select a Card Pack!')
.setDisabled(false)
packs.forEach(item =>
select.addOptions(
new StringSelectMenuOptionBuilder()
.setLabel(item.packName)
.setDescription(`A ${item.packTier} Card Pack. Price: ${item.packCost} Gold`)
.setEmoji('🃏')
.setValue(item.packId),
)
);

const row1 = new ActionRowBuilder()
.addComponents(select);

await interaction.reply({components: [row1], ephemeral: true});
const response = await interaction.fetchReply();

const filters = i => (i.user.id === interaction.user.id);
const selection = await response.createMessageComponentCollector({filter: filters, componentType: ComponentType.StringSelect});

selection.on('collect', async i => {
await interaction.deleteReply();
await i.reply({content: `Confirm your purchase for ${i.values[0]}?`, components: [row2], ephemeral: true});
const response2 = await i.fetchReply();
const confirmButt = await response2.createMessageComponentCollector({filter: filters, componentType: ComponentType.Button});

confirmButt.on('collect', async i => {
if (i.customId === 'confirm-shop-buy') {
const map = selection.collected.first();
//console.log(map.values[0], "SELECTION");
const bResponse = await userAddPack(map.values[0], i.member.id);
await i.followUp(bResponse);
}
})
});


}
}

},
};
module.exports = {
name: Events.InteractionCreate,
async execute(interaction) {


if(interaction.type == InteractionType.MessageComponent) {
if(interaction.customId == 'view-shop') {

const packs = await Packs.find();
const select = new StringSelectMenuBuilder()
.setCustomId('cards')
.setPlaceholder('Select a Card Pack!')
.setDisabled(false)
packs.forEach(item =>
select.addOptions(
new StringSelectMenuOptionBuilder()
.setLabel(item.packName)
.setDescription(`A ${item.packTier} Card Pack. Price: ${item.packCost} Gold`)
.setEmoji('🃏')
.setValue(item.packId),
)
);

const row1 = new ActionRowBuilder()
.addComponents(select);

await interaction.reply({components: [row1], ephemeral: true});
const response = await interaction.fetchReply();

const filters = i => (i.user.id === interaction.user.id);
const selection = await response.createMessageComponentCollector({filter: filters, componentType: ComponentType.StringSelect});

selection.on('collect', async i => {
await interaction.deleteReply();
await i.reply({content: `Confirm your purchase for ${i.values[0]}?`, components: [row2], ephemeral: true});
const response2 = await i.fetchReply();
const confirmButt = await response2.createMessageComponentCollector({filter: filters, componentType: ComponentType.Button});

confirmButt.on('collect', async i => {
if (i.customId === 'confirm-shop-buy') {
const map = selection.collected.first();
//console.log(map.values[0], "SELECTION");
const bResponse = await userAddPack(map.values[0], i.member.id);
await i.followUp(bResponse);
}
})
});


}
}

},
};

Did you find this page helpful?