0
votes

I am making a Discord bot in Node.js where I make an API Call to fetch a person's ranks in a game, to then apply a rank role to that person in the server.

Before applying that role, I have to first remove all the current roles from that person, to then apply the new rank role.

Problem is that this is asynchronous, so I start removing all the roles and when I add the new role, it is still removing roles, causing the new role to get removed instantly.

I can't wrap my head around callbacks and promises, so I don't know how to proceed. Following is my code:

for(var i = 0; i < allranks.length; i++){
        var role = message.member.guild.roles.find('name', allranks[i]);
        message.member.removeRole(role).catch(err => console.log(err));
    }

setTimeout(function(){
    var role = message.member.guild.roles.find('name', ranks[highestRank]);

    message.member.addRole(role).catch(err => console.log(err));

    message.reply("Rank updated to " + highestRank);

}, 2000)

As you can see, i'm setting a Timeout to wait for the rank removal to finish, before applying the new role. I know this is very bad and inefficient, so can someone help me out with either a callback or a promise?

2
I would recommend you use await/async - the code would be simple and much more readable.Florin Toader

2 Answers

0
votes

For carrying a series of promise , you should Promise.all

Promise.all(allranks.map(function(eachrank){
          var role = message.member.guild.roles.find('name',eachrank);
          return message.member.removeRole(role) ;   
    })).then(function(data){
          var role = message.member.guild.roles.find('name', ranks[highestRank]);
          return message.member.addRole(role)
    }).then(function(){
          return message.reply("Rank updated to " + highestRank)

    }).catch(function(err){
          console.log(err);
    })
0
votes

You should learn to work with async/await, it'll pay off.
With that you can do:

async function updateRank(member) {
    for(const i = 0; i < allranks.length; i++){
        const role = message.member.guild.roles.find('name', allranks[i]);
        await message.member.removeRole(role); //Notice the await.
    }

    const role = message.member.guild.roles.find('name', ranks[highestRank]);

    await message.member.addRole(role); //Notice the await here too.
    message.reply("Rank updated to " + highestRank);
}

The keyword await will make it so the code will wait until the promise is resolved (and also returns the promised object).
We don't need the object, we just want to wait.

I also changed some vars to const. I recommend using let and const too.