pagination with button handler

Hello i want to refactor my current embed pagination. How do I update the embed in a separate button handler? A user starts a slashcommand where I create n embeds where n: n >= 1. the customId of the two buttons are in this format RESERVATION-NEXT-' /*spotId*/, RESERVATION-BACK-' /*spotId*/, In my button handler (interactionCreate.ts) i dont know how I access the embeds from my slashcommand which I have created to edit the current embed
} else if (interaction.isButton()) {
const button = interaction.client.buttons.get(interaction.customId);
if (!button) {
if (interaction.customId.startsWith('RESERVATION-NEXT-' /*spotId*/) && interaction.customId.split('-').length === 3) {
return await handleSpotNextButton(interaction);
}
if (interaction.customId.startsWith('RESERVATION-BACK-' /*spotId*/) && interaction.customId.split('-').length === 3) {
return await handleSpotBackButton(interaction);
}
console.error(`No interaction matching ${interaction.customId} was found.`);
return;
}
try {
if (!button.execute) return;
button.execute(interaction, userState);
} catch (error) {
console.error(error);
}
} else if (interaction.isButton()) {
const button = interaction.client.buttons.get(interaction.customId);
if (!button) {
if (interaction.customId.startsWith('RESERVATION-NEXT-' /*spotId*/) && interaction.customId.split('-').length === 3) {
return await handleSpotNextButton(interaction);
}
if (interaction.customId.startsWith('RESERVATION-BACK-' /*spotId*/) && interaction.customId.split('-').length === 3) {
return await handleSpotBackButton(interaction);
}
console.error(`No interaction matching ${interaction.customId} was found.`);
return;
}
try {
if (!button.execute) return;
button.execute(interaction, userState);
} catch (error) {
console.error(error);
}
2 Replies
d.js toolkit
d.js toolkit3w ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
Skylife
Skylife3w ago
so what I want is to have the logic collector.on in my handleSpotNext/BackButton
export const pagination = async (interaction, embeds: EmbedBuilder[], time = 30 * 1000) => {
try {
if (!interaction || !embeds) throw new Error("[PAGINATION] Invalid parameters")
// await interaction.deferReply();
if (embeds.length === 1) return await interaction.channel!.send({embeds, fetchReply: true});
let index = 0;
const first = new ButtonBuilder()
.setCustomId("pagefirst")
.setEmoji("⏪")
.setStyle(ButtonStyle.Primary)
.setDisabled(true);

const prev = new ButtonBuilder()
.setCustomId("pageprev")
.setEmoji("◀")
.setStyle(ButtonStyle.Primary)
.setDisabled(true);

const pageCount = new ButtonBuilder()
.setCustomId("pagecount")
.setLabel(`${index + 1}/${embeds.length}`)
.setStyle(ButtonStyle.Primary)
.setDisabled(true);

const next = new ButtonBuilder()
.setCustomId("pagenext")
.setEmoji("▶")
.setStyle(ButtonStyle.Primary)

const last = new ButtonBuilder()
.setCustomId("pagelast")
.setEmoji("⏩")
.setStyle(ButtonStyle.Primary)

const buttons = new ActionRowBuilder().addComponents([first, prev, pageCount, next, last]);
const msg = await interaction.channel!.send({embeds: [embeds[index]], components: [buttons], fetchReply: true});
const collector = msg.createMessageComponentCollector({
componentType: ComponentType.Button,
});
export const pagination = async (interaction, embeds: EmbedBuilder[], time = 30 * 1000) => {
try {
if (!interaction || !embeds) throw new Error("[PAGINATION] Invalid parameters")
// await interaction.deferReply();
if (embeds.length === 1) return await interaction.channel!.send({embeds, fetchReply: true});
let index = 0;
const first = new ButtonBuilder()
.setCustomId("pagefirst")
.setEmoji("⏪")
.setStyle(ButtonStyle.Primary)
.setDisabled(true);

const prev = new ButtonBuilder()
.setCustomId("pageprev")
.setEmoji("◀")
.setStyle(ButtonStyle.Primary)
.setDisabled(true);

const pageCount = new ButtonBuilder()
.setCustomId("pagecount")
.setLabel(`${index + 1}/${embeds.length}`)
.setStyle(ButtonStyle.Primary)
.setDisabled(true);

const next = new ButtonBuilder()
.setCustomId("pagenext")
.setEmoji("▶")
.setStyle(ButtonStyle.Primary)

const last = new ButtonBuilder()
.setCustomId("pagelast")
.setEmoji("⏩")
.setStyle(ButtonStyle.Primary)

const buttons = new ActionRowBuilder().addComponents([first, prev, pageCount, next, last]);
const msg = await interaction.channel!.send({embeds: [embeds[index]], components: [buttons], fetchReply: true});
const collector = msg.createMessageComponentCollector({
componentType: ComponentType.Button,
});
collector.on("collect", async (interaction: CollectedMessageInteraction) => {
await interaction.deferUpdate();
if (interaction.customId === "pagefirst") {
pageCount.setLabel(`${index + 1}/${embeds.length}`)
}
if (interaction.customId === "pageprev") {
if (index > 0) index--;
pageCount.setLabel(`${index + 1}/${embeds.length}`)
} else if (interaction.customId === "pagenext") {
if (index < embeds.length - 1) {
index++;
pageCount.setLabel(`${index + 1}/${embeds.length}`)
}
} else if (interaction.customId === "pagelast") {
index = embeds.length - 1;
pageCount.setLabel(`${index + 1}/${embeds.length}`)
}
if (index === 0) {
first.setDisabled(true);
prev.setDisabled(true);
} else {
first.setDisabled(false);
prev.setDisabled(false);
}
if (index === embeds.length - 1) {
next.setDisabled(true);
last.setDisabled(true);
} else {
next.setDisabled(false);
last.setDisabled(false);
}
await msg.edit({embeds: [embeds[index]], components: [buttons]}).catch(err => {
});
});
return msg;
} catch (error) {
console.error(error)
}
}
collector.on("collect", async (interaction: CollectedMessageInteraction) => {
await interaction.deferUpdate();
if (interaction.customId === "pagefirst") {
pageCount.setLabel(`${index + 1}/${embeds.length}`)
}
if (interaction.customId === "pageprev") {
if (index > 0) index--;
pageCount.setLabel(`${index + 1}/${embeds.length}`)
} else if (interaction.customId === "pagenext") {
if (index < embeds.length - 1) {
index++;
pageCount.setLabel(`${index + 1}/${embeds.length}`)
}
} else if (interaction.customId === "pagelast") {
index = embeds.length - 1;
pageCount.setLabel(`${index + 1}/${embeds.length}`)
}
if (index === 0) {
first.setDisabled(true);
prev.setDisabled(true);
} else {
first.setDisabled(false);
prev.setDisabled(false);
}
if (index === embeds.length - 1) {
next.setDisabled(true);
last.setDisabled(true);
} else {
next.setDisabled(false);
last.setDisabled(false);
}
await msg.edit({embeds: [embeds[index]], components: [buttons]}).catch(err => {
});
});
return msg;
} catch (error) {
console.error(error)
}
}
because when the bot restarts etc. the interaction fails true thx so maybe i implement paginatioon oin my api so i always fetch the current page what do you think? the data for the embed i get through my backend(API) and my idea is now i just create one embed in the beginning then when the user press the next button i fetch the second page from my backend and edit the current embed with the new data What do you mean data does not change it is possible that the data is changing Ah okay understood no it’s not like that every page has different data