How to return Mongoose query results without callback How to return Mongoose query results without callback mongodb mongodb

How to return Mongoose query results without callback


Use the Async/Await Syntax:

const findUser = async function (params) {     try {  return await User.findOne(params)    } catch(err) { console.log(err) }}const userSteve = findUser({firstName: Steve})

Each time you need to use the information from a Query, use the await prefix within an async function. This will allow you to use asynchronous nature of a Mongoose query within synchronous code that needs that query result to continue.

For your code:

coreModule.findUser  = async function (userId) {     return await User.findOne({id:_userId})}coreModule.findPosts = async function(authorId) {    return await Posts.find({postedBy: authorId})}const foundUser = coreModule.findUser(123);const foundPosts = coreModule.findPosts(123);res.send({user: foundUser, posts: foundPosts}) 

If you would like both queries to fire off simultaneously, you can use Promise.all()

coreModule.findUser  =  function (userId) {     return User.findOne({id:_userId})}coreModule.findPosts = function(authorId) {    return Posts.find({postedBy: authorId})}const [foundUser, foundPosts] =    await Promise.all(         [coreModule.findUser(123), coreModule.findPosts(123)]   ); res.send({user: foundUser, posts: foundPosts})

If you have both Queries located at separate EndPoints in your API, you could also construct two fetch requests aimed at both endpoints and fire those off simultaneously on the Client-Side with Promise.all()

I hope this helped!

Edit: I have edited my post with this working example which I have tested in my API:

module.exports.test = async function(req, res, next) {    const module1 = function(params) {        return ShoppingCartModel.find({_id: params})    }    const module2 = function(params) {        return User.find({_id: params})    }    const array = [module1('5a739dbc45424d2904faca5b'), module2('5a739dbc45524d2904faca5b')]    const promise = await Promise.all(array)    res.json(promise)}

Some examples of incorrect returns:

Incorrect:

const array = [ShoppingCartModel.find({}), ShoppingCartModel.find({})]// console.log(array) = Mongoose Query Constructorsconst promise = Promise.all(array)// console.log(promise) = Promise { <pending> }

Correct:

const array = [ShoppingCartModel.find({}), ShoppingCartModel.find({})]const promise = await Promise.all(array)

Incorrect:

// Return full fledged promise from Mongoose query using .exec()const array = [ShoppingCartModel.find({}).exec(), ShoppingCartModel.find({}).exec()]// console.log(array) = [ Promise { <pending> }, Promise { <pending> } ]const promise = Promise.all(array)// console.log(promise) = Promise { <pending> }

Correct:

const array = [ShoppingCartModel.find({}).exec(), ShoppingCartModel.find({}).exec()]    const promise = await Promise.all(array)

You must await the result of Promise.all, or else your function will blow through the function calls, send an empty JSON object back to the front-end, and console.log pending promises which are not given time to resolve


As far as calling db is an asynchronous thing, you have to wait for the response in an asynchronous way. But, callbacks aren't the only way.You can use promises, with came to have cleaner code.It looked like this:

coreModule.findUser({id:123}).then(user => {    return coreModule.findPosts({author:123});}).then(posts => {    res.render("home", {user:user, posts:posts});});

And the mongoose part should responde a promise instead using callbacks, like this:

//core module examplefindUser: function(params){   return User.findOne(params).lean(true).exec();}

Hope it helps


const findBook = async (queryParams) => {     try {           return await Book.findOne(params)    } catch(error) {           // handle the errors  }}const getBook = async (req, res) =>{    try{     const book = findBook(queryParams);     // next code goes here    }catch(error){          // handle the errors    }}