psibean / discord.js-pagination

A simple (or advanced - it's your choice) utility to paginate discord embeds. Configure, customise, and control!
MIT License
10 stars 8 forks source link

pages must be provided if not using a pageEmbedResolver #14

Closed ryuujo closed 2 years ago

ryuujo commented 2 years ago

Recently I tried to make embed pagination and got this error. I've check your documentation multiple times but it still didn't understand what is that mean. What I use is basically like this

const { ButtonPaginator } = require('@psibean/discord.js-pagination');

...
...
async execute(message, args) {
    const scheduleEmbed = (data) => {
      const newData = [];
      for (let i = 0; i < data.length; i += 5) {
        const chunk = data.slice(i, i + 5);
        newData.push(chunk);
      }
      const listEmbeds = [];
      newData.slice(0, 10).map((data, index) => {
        const embed = {
          ...all embed data...
        };
        listEmbeds.push(embed);
      });
      //expected result should be: [{embedData1},{embedData2},...,{embedData10}]
      const selectPaginator = new ButtonPaginator(message, { listEmbeds });
      selectPaginator.send();
    };

How you determine the pages? How to provide pages on this code? and Where we should add the pageEmbedResolver thingy?

psibean commented 2 years ago

Hey! Welcome! Apologies you're struggling to figure this out, let's see if I can clarify things for you.

When you do this line here:

const selectPaginator = new ButtonPaginator(message, { listEmbeds });

You're calling the constructor for the ButtonPaginator, you're passing in a message as the first argument (do note this should be an interaction, not a message).

The second parameter, you're passing in an argument that is an object and you're providing it a property by the name listEmbeds.

The PaginatorOptions describes the arguments you can provide in the second parameter object.

The BaseOptions can be provided to all of the paginators, the ActionRowPaginator options can be provided to both the ActionRowPaginator, ButtonPaginator, and SelectPaginator. Then each one also has their own specific additional options available. Following the readme, this means that for the second parameter for the ButtonPaginator, you can provide the following arguments:

messageSender, pageEmbedResolver, useCach, maxPageCache, messageOptionsResolver, collectorOptions, identifiersResolver, shouldChangePage, footerResolver (this one may be obsolete), initialIdentifiers, messageActionRows, customIdPrefix, buttons

You'll notice that there is no property that you can provide within the second parameter named "listEmbeds".

However, this is my bad! It looks like the readme doesn't specify that you need to provide the pages property as part of the second parameter object if you're creating them upfront, otherwise you can use the pageEmbedResolver to create the embeds dynamically.

Please refer to the working example code in the repository which shows how to use the paginators!

If you go to the example readme it has gifs demonstrating the different commands in the example. Then, you can look at the basic button paginator example, the custom button paginator example, or if you want an example of how the page embed resolver works, there is also the dynamic button paginator example.

But, do note, as mentioned, these won't work unless you provide an interaction (CommandInteraction) from the interactionCreate event, it is impossible to access the components and interaction API without using an interaction.

ryuujo commented 2 years ago

where do I get the interaction of that you mentioned? Is that came from the async? because your code sometimes use this kind async-await function

async(interaction){
   ...
}

I used message and basically come from discordjs and thought it can be replaced with that. Let me know if I did wrong on that step.

psibean commented 2 years ago

where do I get the interaction of that you mentioned?

As I mentioned, the interaction comes from the interactionCreate event, this is shown as an event on the client in the discordjs documentation and there's a complete discordjs guide on how to setup a bot, this part shows you how to use the interactionCreate event.

Is that came from the async? because your code sometimes use this kind async-await function

No, as mentioned above, the interaction comes from the interactionCreate event, this is discordjs specific.

async stands for asynchronous and is the opposite of synchronous, these are JavaScript terms, if you don't understand them or you aren't familiar with them, I'd recommend you check out the learnjavascript subreddit, especially if you can't read the discordjs documentation, or if you don't completely understand the guide (events, callbacks, promises, etc).

I used message and basically come from discordjs and thought it can be replaced with that. Let me know if I did wrong on that step.

Thought that what could be replaced with what? If you thought discordjs could be replaced by this, no, you need both, this is just a package that you use in addition to discordjs that provides some API / structure to paginating embeds, albeit it isn't great.

The example app previously linked also shows you how to utilize the interactionCreate event and register slash commands as per the official discordjs guide linked above:

client.on('interactionCreate', async interaction => {
  if (!interaction.isCommand()) return;

  const { commandName } = interaction;

  if (!client.commands.has(commandName)) return;

  try {
    await interaction.deferReply({ ephemeral: true });
    await client.commands.get(commandName).execute(interaction);
  } catch (error) {
    console.error(error);
    await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
  }
});
psibean commented 2 years ago

Going to close this for now, the specified error is just an issue with usage, it's an expected error when neither of the pages and pageEmbedResolver option is provided.