Search code examples
javascriptdiscorddiscord.jsbotschatbot

Receiving DiscordJS Promise Object Instead of Resolution For Fetch User Nickname


I am trying to create a ranking list/leaderboard, however when trying to map the values, a promise object and not a string is returned. I understand that with fetch I need to handle the promise using .then(), however I can’t figure out how to pass the resolved promise to item in the map function so that the output is correct.

Intended Output Formatted:

LeaderBoard:
<Username> - <# Of Points>
.
.
.
.
.
<Last Username> - <Last # Of Points>

Code:

const buildLeaderBoard = async () => {
  const list = await db.collection("Karma").find({}, {upsert: true}).sort({ karma: -1 }).toArray()
    mappedlist = list.map(async function(item){
    item = await client.users.fetch(`${item.member}`).then((value) =>{
    return `${value.nickname} - ${item.karma}`;
    });
    return item;
    }).join(`\n`);

Current Output:


Solution

  • Array.map() will not work for async functions by itself. You instead can use a for loop:

    const buildLeaderBoard = async () => {
      const list = await db.collection("Karma")
          .find({}, {upsert: true})
          .sort({ karma: -1 }).toArray(),
        mappedList = [];
      for (let i = 0; i < list.length; i++) {
        const item = list[i],
          value = await client.users.fetch(`${item.member}`)
            .then((value) => {
              return `${value.nickname} - ${item.karma}`;
            });
        mappedList.push(value);
      }
      return mappedList.join("\n");
    }
    

    You can also make use of Promise.all():

    const buildLeaderBoard = async () => {
      const list = await db.collection("Karma")
          .find({}, {upsert: true})
          .sort({ karma: -1 }).toArray(),
        mappedList = list.map(async (item) => {
          const data = await client.users.fetch(`${item.member}`)
            .then((value) => `${value.nickname} - ${item.karma}`)
          return data;
        });
    
      return (await Promise.all(mappedList)).join("\n");
    
    }