Home > OS >  How to resolve promise in if statement?
How to resolve promise in if statement?

Time:09-12

I have an array of objects as: { id: '1582715', email: '[email protected]', isUsed: false }, and I have many documents in MongoDB with same keys. Before writing new array of objects in BD, I want to check does objects of array already been written to DB.

I wrote this func that returns array of objects that hasn't been written yet:

const forWriting = testimonalsArray.filter(isWritten => {
    if (collection.countDocuments({ id: { $eq: isWritten.id } }) < 1) return isWritten
})
console.log(forWriting)

BUT collection.countDocuments({ id: { $eq: isWritten.id } } returns Promise { <pending> }. I've tried add async await:

const forWriting = testimonalsArray.filter(async isWritten => {
    if (await collection.countDocuments({ id: { $eq: isWritten.id } }) < 1) return isWritten
})
console.log(forWriting)

but still didn't receive any result. How should I resolve this promise to have an integer to compare it with 1?

CodePudding user response:

Since the result can only become available in some future, you cannot expect that the assignment to forWriting will be the result you need, since that assignment happens now, while the result is only there in some future.

You can do it however in an asynchronously executed callback (in the future), using Promise.all:

Promise.all(testimonalsArray.map(isWritten => 
    collection.countDocuments({ id: { $eq: isWritten.id } })
)).then(counts => {
    const forWriting = counts.map((count, i) => count < 1 && testimonalsArray[i])
                             .filter(Boolean);
                             
    console.log(forWriting);
});

This assumes that testimonalsArray will not change while awaiting the counts to come back from the backend.

CodePudding user response:

You should create an async function and first await for collection.countDocuments({ id: { $eq: isWritten.id } }), and then use resolved value. Like this

(async () => {
   const dbRequest = await collection.countDocuments({ id: { $eq: isWritten.id } });
   const forWriting = testimonalsArray.filter(isWritten => {
      if (dbRequest < 1) return isWritten
   })
   console.log(forWriting)
})()

CodePudding user response:

You can filter all matching documents in the collection with this single query. Here is a snippet to use in an async callback, more performant at the same time since it queries DB just a single time.

const testimonialsAlreadyInTheDB = await collection.find({
   id: { $in: testimonalsArray.map(({id}) => id)}
})

const forWriting = testimonialsArray.filter(({id}) => !testimonialsAlreadyInTheDB.find(id))
  • Related