0
 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.

SJoshi
  • 13
  • 2

2 Answers2

1

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.

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39
0
  1. forEach doesn't return anything (it mutates an array in place) so promises will always be undefined. Use map instead which returns a new array.

  2. There's no need for the map callback to be async, and there's no need to await the find process. Simply return the promise.

  3. promises will now be an array so you don't need to wrap it in a new array in Promise.all.

    const promises = books.map(book => {
      return User.find({ _id: book.Owner });
    });
    
    const ownerInformation = await Promise.all(promises);
    
    console.log(ownerInformation);
    
Andy
  • 61,948
  • 13
  • 68
  • 95