PaginatedMessage: There are no actions

This error is being thrown when your actions is empty tho I have only PageActions. Is Having a BaseAction a must?
private async sendMenu(interactionOrMessage: Message | AnyInteractableInteraction) {
const radioStations = radioList; // await Radio.findAll();
const chunkSize = 10;
const paginatedMessage = new PaginatedMessageEmbedFields()
.setActions([])
.setTemplate({
title: 'Radio Stations'
})
.setItems(
radioStations.map((radioStation) => ({
name: radioStation.name,
value: radioStation.url,
inline: false
}))
)
.setItemsPerPage(chunkSize)
.make();

for (let i = 0; i < radioStations.length; i += chunkSize) {
paginatedMessage.setPageActions(
[
{
style: ButtonStyle.Primary,
label: '◀',
customId: 'back-page',
type: ComponentType.Button,
run: async () => {
if (paginatedMessage.hasPage(paginatedMessage.index - 1)) {
paginatedMessage.setIndex(paginatedMessage.index - 1);
}
}
},
{
style: ButtonStyle.Secondary,
label: `${Math.round((i + chunkSize) / chunkSize)}/${Math.round(radioStations.length / chunkSize)}`,
customId: 'cur-page',
type: ComponentType.Button,
disabled: true
},
{
style: ButtonStyle.Primary,
label: '▶',
customId: 'next-page',
type: ComponentType.Button,
run: async () => {
if (paginatedMessage.hasPage(paginatedMessage.index + 1)) {
paginatedMessage.setIndex(paginatedMessage.index + 1);
}
}
}
],
Math.round(i / chunkSize)
);
}

// paginatedMessage.addAction({
// customId: 'add-radio',
// label: 'Placeholder action to escape the error',
// style: ButtonStyle.Primary,
// type: ComponentType.Button,
// disabled: true
// });

paginatedMessage.run(interactionOrMessage);
}
private async sendMenu(interactionOrMessage: Message | AnyInteractableInteraction) {
const radioStations = radioList; // await Radio.findAll();
const chunkSize = 10;
const paginatedMessage = new PaginatedMessageEmbedFields()
.setActions([])
.setTemplate({
title: 'Radio Stations'
})
.setItems(
radioStations.map((radioStation) => ({
name: radioStation.name,
value: radioStation.url,
inline: false
}))
)
.setItemsPerPage(chunkSize)
.make();

for (let i = 0; i < radioStations.length; i += chunkSize) {
paginatedMessage.setPageActions(
[
{
style: ButtonStyle.Primary,
label: '◀',
customId: 'back-page',
type: ComponentType.Button,
run: async () => {
if (paginatedMessage.hasPage(paginatedMessage.index - 1)) {
paginatedMessage.setIndex(paginatedMessage.index - 1);
}
}
},
{
style: ButtonStyle.Secondary,
label: `${Math.round((i + chunkSize) / chunkSize)}/${Math.round(radioStations.length / chunkSize)}`,
customId: 'cur-page',
type: ComponentType.Button,
disabled: true
},
{
style: ButtonStyle.Primary,
label: '▶',
customId: 'next-page',
type: ComponentType.Button,
run: async () => {
if (paginatedMessage.hasPage(paginatedMessage.index + 1)) {
paginatedMessage.setIndex(paginatedMessage.index + 1);
}
}
}
],
Math.round(i / chunkSize)
);
}

// paginatedMessage.addAction({
// customId: 'add-radio',
// label: 'Placeholder action to escape the error',
// style: ButtonStyle.Primary,
// type: ComponentType.Button,
// disabled: true
// });

paginatedMessage.run(interactionOrMessage);
}
No description
Solution:
@Saitama can you test the Pr with pnpm add @sapphire/discord.js-utilities@pr-684?
Jump to solution
10 Replies
Favna
Favna13mo ago
Just add your back button that you're currently adding to each page individually to the global actions. There is no reason for it to be page specific because it uses no page specific data. And you can also add your next page button to the overall ones. The second parameter of setPageActions let you set the index at which the page actions should be inserted, so set it to 1 and your custom action will be in between back and next
Saitama
SaitamaOP13mo ago
The second parameter of setPageActions inserts at page (index) I inserted but setting it as 1 doesn't make it inbetween next and back button but rather just adds it at page with index 1
No description
No description
Favna
Favna13mo ago
oh oops
Saitama
SaitamaOP13mo ago
no worries at first I got confused too Here's code
private async sendMenu(interactionOrMessage: Message | AnyInteractableInteraction) {
const radioStations = radioList; // await Radio.findAll();
const chunkSize = 10;
const paginatedMessage = new PaginatedMessageEmbedFields()
.setActions([])
.setTemplate({
title: 'Radio Stations',
color: parseInt(getRandomHexColor().replace('#', ''), 16)
})
.setItems(
radioStations.map((radioStation) => ({
name: `${getEmojiBasedOnString(radioStation.name)} ${radioStation.name}`,
value: radioStation.url,
inline: false
}))
)
.setItemsPerPage(chunkSize)
.make()
.addActions([
{
style: ButtonStyle.Primary,
label: '◀',
customId: 'back-page',
type: ComponentType.Button,
run: async () => {
if (paginatedMessage.hasPage(paginatedMessage.index - 1)) {
paginatedMessage.setIndex(paginatedMessage.index - 1);
}
}
},
{
style: ButtonStyle.Primary,
label: '▶',
customId: 'next-page',
type: ComponentType.Button,
run: async () => {
if (paginatedMessage.hasPage(paginatedMessage.index + 1)) {
paginatedMessage.setIndex(paginatedMessage.index + 1);
}
}
}
])

for (let i = 0; i < radioStations.length; i += chunkSize) {
paginatedMessage.setPageActions(
[
{
style: ButtonStyle.Secondary,
label: `${Math.round((i + chunkSize) / chunkSize)}/${Math.round(radioStations.length / chunkSize)}`,
customId: 'cur-page',
type: ComponentType.Button,
disabled: true
},
{
customId: 'select-radio',
placeholder: 'Выбрать Радио',
type: ComponentType.StringSelect,
options: radioStations.slice(i, i + chunkSize).map(radioStation => ({
label: radioStation.name,
value: radioStation.name,
emoji: getEmojiBasedOnString(radioStation.name)
}))
}
],
1
);
}

paginatedMessage.addActions([
{
customId: 'add-radio',
emoji: '➕',
label: 'Добавить Радио',
style: ButtonStyle.Primary,
type: ComponentType.Button,
disabled: true
}
]);

paginatedMessage.run(interactionOrMessage);
}
private async sendMenu(interactionOrMessage: Message | AnyInteractableInteraction) {
const radioStations = radioList; // await Radio.findAll();
const chunkSize = 10;
const paginatedMessage = new PaginatedMessageEmbedFields()
.setActions([])
.setTemplate({
title: 'Radio Stations',
color: parseInt(getRandomHexColor().replace('#', ''), 16)
})
.setItems(
radioStations.map((radioStation) => ({
name: `${getEmojiBasedOnString(radioStation.name)} ${radioStation.name}`,
value: radioStation.url,
inline: false
}))
)
.setItemsPerPage(chunkSize)
.make()
.addActions([
{
style: ButtonStyle.Primary,
label: '◀',
customId: 'back-page',
type: ComponentType.Button,
run: async () => {
if (paginatedMessage.hasPage(paginatedMessage.index - 1)) {
paginatedMessage.setIndex(paginatedMessage.index - 1);
}
}
},
{
style: ButtonStyle.Primary,
label: '▶',
customId: 'next-page',
type: ComponentType.Button,
run: async () => {
if (paginatedMessage.hasPage(paginatedMessage.index + 1)) {
paginatedMessage.setIndex(paginatedMessage.index + 1);
}
}
}
])

for (let i = 0; i < radioStations.length; i += chunkSize) {
paginatedMessage.setPageActions(
[
{
style: ButtonStyle.Secondary,
label: `${Math.round((i + chunkSize) / chunkSize)}/${Math.round(radioStations.length / chunkSize)}`,
customId: 'cur-page',
type: ComponentType.Button,
disabled: true
},
{
customId: 'select-radio',
placeholder: 'Выбрать Радио',
type: ComponentType.StringSelect,
options: radioStations.slice(i, i + chunkSize).map(radioStation => ({
label: radioStation.name,
value: radioStation.name,
emoji: getEmojiBasedOnString(radioStation.name)
}))
}
],
1
);
}

paginatedMessage.addActions([
{
customId: 'add-radio',
emoji: '➕',
label: 'Добавить Радио',
style: ButtonStyle.Primary,
type: ComponentType.Button,
disabled: true
}
]);

paginatedMessage.run(interactionOrMessage);
}
kinda lame tho that I don't have full control over action row cus it's managed via library (don't wanna go there and extended, override method) But it is what it is
Saitama
SaitamaOP13mo ago
yea just checked the #GitHub Logs Thankyou
Solution
Favna
Favna13mo ago
@Saitama can you test the Pr with pnpm add @sapphire/discord.js-utilities@pr-684?
Favna
Favna13mo ago
(thought I saw you use pnpm)
Saitama
SaitamaOP13mo ago
yea, I am) It works! Thank you!
Favna
Favna13mo ago
Okay it'll be released soon enough then. We post in #Announcements when it's available and you can claim the ping role through Channels & Roles @Saitama
Want results from more Discord servers?
Add your server