using async and await in nodejs getting Promise { <pending> } - javascript

In my case , i am able to get the token but not the way i wanted ie i do not want to print promise pending and my output after running in tokenDisp.js is :
output: Promise { pending }
t5Npxk5FfnRTj8iHd8vyyfGxnhXR4KQf
login.js:
module.exports = async function doLogin() {
const token = await loginToken();
const myToken = JSON.parse(token);
return console.log(myToken);
};
tokenDisp.js:
const myToken = require('./login.js);
myToken();
Can someone help ?

All async functions return a promise and you still have to use .then() or await on the return value from the async function in order to use that. If you return a value from your async function, it will be the resolved value of the returned promise. If you throw an exception, the exception will be the reason for the rejection of the returned promise.
The use of await inside the function is a convenience INSIDE the async function. It does not magically make an asychronous operation into a synchronous one. So, your function returns a promise. To get the value out of it, use .then() on it.
module.exports = async function doLogin() {
const token = await loginToken();
const myToken = JSON.parse(token);
console.log(myToken);
return myToken; // this will be resolved value of returned promise
};
const myToken = require('./login.js);
myToken().then(token => {
// got token here
}).catch(err => {
console.log(err);
});
Note: your login.js module produces the same result as if it was written like this (without using async or await):
module.exports = function doLogin() {
return loginToken().then(token => {
const myToken = JSON.parse(token);
console.log(myToken);
return myToken; // this will be resolved value of returned promise
});
};

Related

how do i resolve promises

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'
}
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
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]}`)
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.
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"))

When I get firebase data and I log it it returns the document file but when I output it it returns a promise

I have been working with firebase and am having trouble with this code.
The goal of the code is to get the document data with the document id.
const getPostData = async (postId) => {
const postData = await getDoc(doc(db, 'posts', postId));
console.log(postData.data()); // Returns the document data
return postData.data();
}
const postData = getPostData(id);
console.log(postData) // Returns a promise
I am extremely confused because I return the document data which when I log gives me the actual document data but when I set it as a variable it does not do the same.
When you use a function like async, it returns a Promise automatically. So the problem is in logic.
What happens:
You call getPostData
It is an async function, so, its return is Promise
The larger scope is not an async scope, so the console.log is executed right after, not waiting for the execution of what is inside getPostData
console.log returns a Promise
Try something like:
const [postData, setPostData]= useState()
const getPostData = async (postId) => {
const postData = await getDoc(doc(db, 'posts', postId));
if (postData.exists()) {
console.log(postData.data()); // Returns the document data
setPostData(postData.data());
} else {
console.log("No posts!");
}
}
...
getPostData(id);
...
console.log(postData)
Since you've marked getPostData as async it returns a Promise and not an immediate value.
To get the value from the promise when calling getPostData, you can either use then():
getPostData(id).then((postData) => {
console.log(postData)
})
Or you can use await:
const postData = await getPostData(id);
console.log(postData)

return async function undefined in es6

Here, plcs variable within try catch function need to be used outside. I am trying calling async function directly and storing in sync function, both doesn't work, first method shows undefined and next one returns null promise
const fetch = () =>{
const result=async()=>{
try {
const dbResult = await ftchplc();
plcs= dbResult.rows._array;
return plcs
} catch (err) {
throw err;
}
}
return result()
}
const sample = fetch()
console.log(sample)
const result=async()=>{
try {
const dbResult = await ftchplc();
plcs= dbResult.rows._array;
return plcs
} catch (err) {
throw err;
}
}
result()
const sample = result()
ALL async functions return a promise. So you will have to use await or .then() when you call an async function in order to get the resolved value.
async functions are useful INSIDE the function so you can use await internal to the function, but to the outside caller, it's still just a promise being returned. async functions to not turn an asynchronous result into a synchronous result. The caller of an async function still has to deal with an asynchronous response (in a promise).
For example:
async function fn() {
const dbResult = await ftchplc();
return dbResult.rows._array;
};
fn().then(sample => {
console.log(sample);
}).catch(err => {
console.log(err);
});
This assumes that ftchplc() returns a promise that resolves to your expected dbResult.

Calling async function from within async function returns undefined

(Forgive me if the title is inaccurate to the problem this one is boggling the mind)
My application requires that I check a value from the request against the database. For this I created an asynchronous function to query the database:
async function checktoken(){
return prisma.$exists.invalidtoken({token: "testtoken"}).then(result => {
return(result)
})
}
I know that the database call on its own works:
prisma.$exists.invalidtoken({token: "testtoken"}).then(result => {
console.log(result) // returns true
})
In the function that fires at every request I try and call checktoken():
async function getUser(token){
var promise = await checktoken()
var result = promise
console.log(result) //undefined
};
Amending the function to include an explicit call to the database works but only when var promise = await checktoken() is defined before it:
async function getUser(token){
var promise = await checktoken() //When this is removed result1 is undefinded
await prisma.$exists.invalidtoken({token: "testtoken"}).then(result1 => {
console.log("inside db call: "+result1) // true
})
};
I think I have a fundamental misunderstanding of async/await but I am not sure exactly what I am missing.
EDIT:
I have updated my approach taking the advice I received and it still does not work. I am beginning to think my ORM is doing something weird:
async function test(token) {
const status = await prisma.$exists.invalidtoken({ token: token });
console.log(status);
return status;
}
test("123") //logs false (as it should)
async function getUser(token){
var status = await test(token) //logs undefined
console.log(status) //logs undefined
};
An async function requires an await. If you are using the promise.then() technique, then what you would want to do is return a new Promise(), and within the .then call back function resolve the promise
function checktoken() {
return new Promise((resolve,reject) => {
prisma.$exists.invalidtoken({token: "testtoken"}).then(result => {
doSomeOtherStuff();
resolve(result);
});
});
}
Is functionally the same as
async checktoken() {
await prisma.$exists.invalidtoken({token: "testtoken"});
}

How to make `return` respecting async/await in JS?

I'm trying to make this code (a class method) returning a String.
async sign() {
const txt = 'ddddd';
const result = await crypto.createHash('md5').update(txt, 'binary').digest('hex');
return result;
}
The problem is that it ignores await and returns a Promise. This function's returned value is used as a HTTP request header, and while npmlog says it's
apisign: Promise { 'faaa3f1409977cbcd4ac50b5f7cd81ec' }
in network traffic caught by Wireshark I see
apisign: [object Promise]
How do I make return respecting await, or how should I write it so it returns a String?
You should not return the value of an async function as is, since it is a Promise
await for it before serializing it.
An async function always returns a Promise.
If you invoke sign() inside another function then you have to await for it and this requires making the caller function also an async function and so on and so forth.
Eventually, at the top-level code you have to use the regular .then().catch() syntax to wait for the Promise to settle:
sign()
.then((result) => {
// do something with the result (e.g. put it into the response header)
console.log(result);
})
.catch((err) => {
// something wrong happened and the Promise was rejected
// handle the error
console.log(`There was an error: ${err.message || err}`);
});
You will have to await the response of a async function.
const getURL = (title, page) => `https://jsonmock.hackerrank.com/api/movies/search/?Title=${title}&page=${page}`
const callService = async (title, page) => {
let response = await fetch(getURL(title, page));
return await response.json();
}
async function callApi() {
let data = await callService('spiderman', 1);
console.log(data.data.length);
}
callApi();

Categories

Resources