Reputation: 13
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.
Upvotes: 0
Views: 1122
Reputation: 20441
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 _id
s. 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.
Upvotes: 1
Reputation: 63524
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.
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.
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);
Upvotes: 0