Search code examples
javascriptdiscord.js

How to repeatedly prompt for user input until it meets some criteria?


I'm creating a collector in discord.js version 13.6.0. I'm checking a condition to see if the user's message is a number, but if it's not a number then I'd like the code to repeat until the user enters that number. A while loop didn't work for me.

const filter = message => message.author.id == message.author.id
      
const mainMessage = await message.channel.send(`Jak chcesz nazwać swój przedmiot?`)
    .catch((error) => message.channel.send(`Wystąpił nieoczekiwany błąd.\n**${error}**`))

await mainMessage.channel.awaitMessages({ filter: filter, max: 1, time: 900000, errors: ['time'] })
    .then(async collected => {
        const itemName = collected.first().content

        mainMessage.edit({ content: `Nazwa: ${itemName}\nPodaj ile ma kosztować przedmiot.` })

        await mainMessage.channel.awaitMessages({ filter: filter, max: 1, time: 900000, errors: ['time'] })
            .then(async collected => {
                const priceItem = collected.first().content

                if (isNaN(priceItem.content)) {
                    return message.channel.send('Wprowadź liczbę!');
                } else {

                }

                mainMessage.edit({ content: `Nazwa: ${itemName}\nPieniadze: ${priceItem}.` })

Solution

  • To reuse an asynchronous code snippet like this multiple times, you could define it as a recursive function that is called from the NaN validation branch, like this:

    async function getPriceInput(mainMessage, filter) {
        return await mainMessage.channel.awaitMessages({ filter: filter, max: 1, time: 900000, errors: ['time'] })
        .then(async collected => {
            const priceItem = Number(collected.first().content);
    
            // check if priceItem is not a number
            if (isNaN(priceItem)) {
                await mainMessage.reply('Enter a number!');
                return getPriceInput(mainMessage, filter);
            }
    
            return priceItem;
        });
    }
    
    
    async function executeCommand(interaction) {
        const authorFilter = message => message.author.id == interaction.author.id;
    
        const mainMessage = await interaction.channel.send(`What do you want to name your item?`);
    
        await mainMessage.channel.awaitMessages({ filter: authorFilter, max: 1, time: 900000, errors: ['time'] })
        .then(async collected => {
            const itemName = collected.first().content;
        
            mainMessage.edit({ content: `Name: ${itemName}\nEnter how much you want the item to cost.` });
                
            const priceItem = await getPriceInput(mainMessage, authorFilter);
    
            return mainMessage.edit({
                content: `Name: ${itemName}\nPrice: ${priceItem}.`
            });
        })
    }
    

    discord output