Search code examples
javascriptnode.jsmongodbmongoosemongoose-schema

How do I use async await with map in the mongoose?


 const mapLoop = async _ => {
        console.log('Start')
      
        const promises = books.forEach( async (book) => {
            const ownerInfos = await User.find({_id: book.Owner})  
            return ownerInfos;
            
        })
      
        const ownerInformation = await Promise.all([promises])
        console.log(ownerInformation)
      
        console.log('End')
      }
    
 mapLoop();

The books variable consist of objects each with key value pair of nameBook, editionBook, _id, and Owner(which is an id). What I want to do here is find the owner of the book by the id stored in the value "Owner". However, the ownerInformation variable is printing undefined.


Solution

  • forEach() is for performing an action on each array element and does not return you a new array. It also does not respect async/await. So, your next line is reached before any of your database calls are actually completed, not that it would have mattered anyway. With your promises being undefined : await Promise.all([undefined]) returns [undefined]

    Try mapping the books array directly into the promises array. Now, promises is an array of promises and you can use Promise.all with await to get your result.

    
    const promises = books.map(book => User.find({_id: book.Owner});  
               
    const ownerInformation = await Promise.all(promises)
    console.log(ownerInformation)
     
    

    But, there is an optimization you can make where you only have to make one DB query that has all your _ids. This uses the $in() operator, used to search for a field value in a given array:

    const bookOwnerIds = books.map(book => book.Owner);
    const ownerInformation  = await User.find({'_id': { $in : [bookOwnerIds] });  
    

    Also, please check if your .bookOwner is the correct format as a mongoose object id would expect. If not, you will probably have to use something like mongoose.Types.ObjectId(book.Owner) in both of the above cases.