Working case:
async await is working fine when we call a asynchronous function and that function returning a promise resolve()
Not working case:
async await is not working for mongo DB queries
tried then(), async/await
I have 2 JS files.
In one.js file i am importing function which is in functionone.js
WORKING CASE:
When one.js looks like
var functiononestatus = transactions.functionone(req.session.email).then((came) => {
console.log(came); // getting `need to be done at first` message
console.log("exec next")
});
When functionone.js looks like
module.exports.functionone = functionone;
async function functionone(email) {
return await new Promise((resolve, reject) => {
resolve('need to be done at first')
});
});
NOT WORKING CASE (when mongo db query need to be executed):
When one.js looks like
var functiononestatus = transactions.functionone(req.session.email).then((came) => {
console.log(came); // getting undefined
console.log("exec next")
});
When functionone.js looks like
module.exports.functionone = functionone;
async function functionone(email) {
//mongo starts
var collection = await connection.get().collection('allinonestores');
await collection.find({
"email": email
}).toArray(async function(err, wallcheck) {
return await new Promise((resolve, reject) => {
resolve(wallcheck[0])
});
});
Working case:
async await is working fine when we call a asynchronous function and that function returning a promise resolve()
Not working case:
async await is not working for mongo DB queries
tried then(), async/await
I have 2 JS files.
In one.js file i am importing function which is in functionone.js
WORKING CASE:
When one.js looks like
var functiononestatus = transactions.functionone(req.session.email).then((came) => {
console.log(came); // getting `need to be done at first` message
console.log("exec next")
});
When functionone.js looks like
module.exports.functionone = functionone;
async function functionone(email) {
return await new Promise((resolve, reject) => {
resolve('need to be done at first')
});
});
NOT WORKING CASE (when mongo db query need to be executed):
When one.js looks like
var functiononestatus = transactions.functionone(req.session.email).then((came) => {
console.log(came); // getting undefined
console.log("exec next")
});
When functionone.js looks like
module.exports.functionone = functionone;
async function functionone(email) {
//mongo starts
var collection = await connection.get().collection('allinonestores');
await collection.find({
"email": email
}).toArray(async function(err, wallcheck) {
return await new Promise((resolve, reject) => {
resolve(wallcheck[0])
});
});
Share
Improve this question
edited Jan 4, 2019 at 7:58
Erdogan Oksuz
62111 silver badges17 bronze badges
asked Jan 4, 2019 at 5:57
user4743671user4743671
10
-
1
In the second,
functionone
isn't returning anything, thusundefined
– CertainPerformance Commented Jan 4, 2019 at 6:00 -
actually we are getting values in
wallcheck[0]
(in the second function) but code one.js is getting undefined eventhough we have values inwallcheck[0]
– user4743671 Commented Jan 4, 2019 at 6:01 -
1
Yes, because your
functionone
is not returning anything. – CertainPerformance Commented Jan 4, 2019 at 6:02 - I understood that, but y is the question? – user4743671 Commented Jan 4, 2019 at 6:03
-
1
It's not returning anything because you have no
return
statement in the function. Try usingreturn
to return the Promise. – CertainPerformance Commented Jan 4, 2019 at 6:04
2 Answers
Reset to default 6Quick clarification:
.collection('name')
returns aCollection
instance, not a Promise, so no need toawait
for it.toArray()
operates in two modes: either with a callback when a function is provided, either returns a Promise when no callback function is provided.
You're essentially expecting a Promise result out of toArray()
while supplying a callback function, resulting in undefined
, because callback takes priority and no promise is returned, due to the dual operation mode of toArray().
Also, toArray(callback)
does not take an async
function as callback.
Here's how your code should look like, for retrieving a collection:
const client = await MongoClient.connect('your mongodb url');
const db = client.db('your database name'); // No await here, because it returns a Db instance.
const collection = db.collection('allinonestores'); // No await here, because it returns a Collection instance.
and then, code for fetching results:
const db = <get db somehow>;
// You could even ditch the "async" keyword here,
// because you do not do/need any awaits inside the function.
// toArray() without a callback function argument already returns a promise.
async function functionOne(email) {
// Returns a Collection instance, not a Promise, so no need for await.
const collection = db.collection('allinonestore');
// Without a callback, toArray() returns a Promise.
// Because our functionOne is an "async" function, you do not need "await" for the return value.
return collection.find({"email": email}).toArray();
}
and code alternative, using callback:
const db = <get db somehow>;
// You could even ditch the "async" keyword here,
// because you do not do/need any awaits inside the function.
// You're forced to return a new Promise, in order to wrap the callback
// handling inside it
async function functionOne(email) {
// Returns a Collection instance, not a Promise, so no need for await.
const collection = db.collection('allinonestore');
// We need to create the promise outside the callback here.
return new Promise((resolve, reject) => {
db.find({"email": email}).toArray(function toArrayCallback(err, documents) {
if (!err) {
// No error occurred, so we can solve the promise now.
resolve(documents);
} else {
// Failed to execute the find query OR fetching results as array someway failed.
// Reject the promise.
reject(err);
}
});
});
}
Note: First of all i really need to thank @mihai Potra for the best answer.
Here we go
Case 1:
If it is a function which need to find documents and return from MongoDb as mihai mentioned, below answer is uber cool
const db = <get db somehow>;
async function functionOne(email) {
const collection = db.collection('allinonestore');
return collection.find({"email": email}).toArray();
}
case 2:
If there are nested functions which need to return values every time below ans will be the best as of my knowledge
-no need async/await keywords for every function or no need then()
function one(<parameter>) {
return new Promise(function(resolve, reject) {
const collection = connection.get().collection('<collection_name>');
const docs = collection.find({"Key": Value_fromFunction}).toArray( function (err, result) {
resolve(result[0]);
});
That's it, use resolve callback when ever it needed.