Home > Software design >  how do i resolve promises
how do i resolve promises

Time:11-11

I read like through 10 pages on how to resolve promises but i still don't get it. Info: I want to fetch a specific member of a discord server

Currently I have a async function with the promise inside that returns it but it gives me a message with "Invalid Body Form"

async function mbr() {
     const mB = await client.guilds.cache.get("1037783624449282189").members.fetch(`${args[0]}`).then((m) => { return m; });
     return mB
}
let member = mbr()

if (member.roles.cache.has("1039983830389510305"))

Edit: It gives me this Error when i do a async Function inside a async function

G:\Desktop\Minecraft Modding\Bedrock\_____\Server\legend\plugins\nodejs\discord-bot\node_modules\@discordjs\rest\dist\index.js:659
        throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData);
              ^

DiscordAPIError[50035]: Invalid Form Body
user_id[NUMBER_TYPE_COERCE]: Value "undefined" is not snowflake.
    at SequentialHandler.runRequest (G:\Desktop\Minecraft Modding\Bedrock\_____\Server\legend\plugins\nodejs\discord-bot\node_modules\@discordjs\rest\dist\index.js:659:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async SequentialHandler.queueRequest (G:\Desktop\Minecraft Modding\Bedrock\_____\Server\legend\plugins\nodejs\discord-bot\node_modules\@discordjs\rest\dist\index.js:458:14)
    at async REST.request (G:\Desktop\Minecraft Modding\Bedrock\_____\Server\legend\plugins\nodejs\discord-bot\node_modules\@discordjs\rest\dist\index.js:902:22)
    at async GuildMemberManager._fetchSingle (G:\Desktop\Minecraft Modding\Bedrock\_____\Server\legend\plugins\nodejs\discord-bot\node_modules\discord.js\src\managers\GuildMemberManager.js:489:18)
    at async mbr (G:\Desktop\Minecraft Modding\Bedrock\_____\Server\legend\plugins\nodejs\discord-bot\chatBridge\accountLink.js:8:32)
    at async G:\Desktop\Minecraft Modding\Bedrock\_____\Server\legend\plugins\nodejs\discord-bot\chatBridge\accountLink.js:11:30 {
  requestBody: { files: undefined, json: undefined },
  rawError: {
    code: 50035,
    errors: {
      user_id: {
        _errors: [
          {
            code: 'NUMBER_TYPE_COERCE',
            message: 'Value "undefined" is not snowflake.'
          }
        ]
      }
    },
    message: 'Invalid Form Body'
  },
  code: 50035,
  status: 400,
  method: 'GET',
  url: 'https://discord.com/api/v10/guilds/1037783624449282189/members/undefined'
}

CodePudding user response:

You have three ways to accomplish this:

Top-level await

Note: If this is an option in your JavaScript runtime.

let member = await mbr();
if (member.roles.cache.has("1039983830389510305")) {
  // ...
}

IIFE async

(async () => {
  let member = await mbr();
  if (member.roles.cache.has("1039983830389510305")) {
    // ...
  }
})();

Promise resolution

mbr()
  .then((member) => {
    if (member.roles.cache.has("1039983830389510305")) {
      // ...
    }
  });

Also, your mbr function can be simplified to:

const mbr = async () =>
  client.guilds.cache
    .get("1037783624449282189").members
    .fetch(`${args[0]}`)

CodePudding user response:

Promises need to be awaited, either by using p.then(callback), or by using await p.

For example, this Promise:

const p = new Promise(resolve => setTimeout(resolve("Hello world!"), 100));

will resolve in 100 ms, and can be used either like this

p.then(message => console.log(message));

or like this

console.log(await p);

In short, your function:

async function mbr() {
     const mB = await client.guilds.cache.get("1037783624449282189").members.fetch(`${args[0]}`).then((m) => { return m; });
     return mB
}

can be resolved by either

mbr().then(member => {
   if (member.roles.cache.has("1039983830389510305")) { ... }
});

or

const member = await mbr();
if (member.roles.cache.has("1039983830389510305")) { ... }

Note that in order to use await, you must be in an async context! By default, Node.js's global scope is synchronous, so you need to wrap your code inside an anonymous async function, like so:

(async () => {

  const member = await mbr();
  if (member.roles.cache.has("1039983830389510305")) { ... }

})();  // <--  call immediately

CodePudding user response:

async/await can be used to make the code for working with promises a lot more concise and readable.

In case you don't know how promises work, here's a quick explanation:

Promises are a way for developers to create asynchronous, non-blocking code that will run "at the same time" as the current code. All promises should eventually resolve or reject, which are callbacks that let developers run extra code after a promise is finished.

In Discord specifically, fetching members creates an api request, which could take any amount of time, so it returns a promise. In order to actually use the data from the promise, you have to retrieve the data after it's resolved, which can be easily accomplished with async/await.

// since this function is async, it will ALWAYS return a promise
async function mbr() {
     // await can be used to pause code execution until the promise resolves
     // you don't need to use `.then()`, because await is already resolving your promise
     const mB = await client.guilds.cache.get("1037783624449282189").members.fetch(`${args[0]}`);
     // return the resolved value of the promise
     return mB
}

// you need to add await here, because mbr() now returns a promise itself
// make sure this code is placed in an async function or use top level awaits
let member = await mbr()

// you can now use the member object and the data it contains
if (member.roles.cache.has("1039983830389510305"))

Hope this helps.

CodePudding user response:

async function mbr() {
     const mB = await client.guilds.cache.get("1037783624449282189").members.fetch(`${args[0]}`).then((m) => { return m; });
     return mB
}
let member = await mbr()

if (member.roles.cache.has("1039983830389510305"))
  • Related