0

I have a list called collectionList, and I am wanting to go through the object list and see if a document in my mongodb collection exists. If it doesn't exist, then it will create a new document for that list item. The new document name should be the same as the name in the object list.

Here is the list:

const collectionList = [
    { name: "pages", schema: pageSchema.pageSchema },
    { name: "posts", schema: postSchema.postSchema }
]

If there is not a document with the name equal to the collectionList[i].name, then I want mongoose to create a new document with the name.

Here is the section of the code that the bug is occurring in:

for (var i = 0; i < collectionList.length; i++) {
    var collectionName = collectionList[i].name
    console.log("collectionList name:",collectionName); // Outputs the collectionList[i].name to make sure it is working
    Collection.countDocuments({ name: collectionName })
        .then((data) => {
            console.log(data)
            if (data == null || data == 0 || data == false) {
                const newCollection = new Collection({
                    name: collectionName,
                    data: []
                })
                newCollection.save().then(() => {
                    console.log('collection saved', collectionName)
                }).catch((err) => {
                    console.log(err)
                })
            } else {
                console.log("I found it, but I don't know what to do!")

            }

        }).catch((err) => {
            console.log(err)
        })
}

My mongodb collection is called Collection and it is empty, there are no documents in it. When I run it, it console logs collectionList name: pages then collectionList name: posts on line 3. When I look in my mongodb collection, the name in both document is posts. Why is it not creating the document with the name: pages? On line 13 when I console log the collectionName, both times it logs posts.

Caleb Gross
  • 391
  • 3
  • 12
  • Does this answer your question? [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Matt Mar 02 '23 at 08:56
  • I just needed to add `await`. It wasn't executing in the right order. Thank you though. – Caleb Gross Mar 02 '23 at 09:00
  • It's worth while to understand why `collectionName` changes in the loop when using `var`, the await just masks that issue. – Matt Mar 02 '23 at 10:17

2 Answers2

1

just correction and opinion:

its a bit confused to use await and then in the same time. then its already promise. and please check the conditional if (data == null || data == 0 || data == false) { . use if(data) instead.

following your description, you just need to use findAndUpdate, reff findOneAndUpdate

if data not exist, then create a new one.

that would be like:

const collectionList = [
    { name: "pages", schema: pageSchema.pageSchema },
    { name: "posts", schema: postSchema.postSchema }
]

const newCollection = new Collection()
for (const key of collectionList) {
    await newCollection.findOneAndUpdate({name: key.name}, {name: key.name}, {upsert:true})
}

or you can use BulkWrite and updateOne for better approach

that would be like:

const collectionList = [
    { name: "pages", schema: pageSchema.pageSchema },
    { name: "posts", schema: postSchema.postSchema }
]

const data = collectionList.map(el => {
    return {
        updateOne: {
            filter: { name: el.name },
            update: { name: el.name },
            options: { upsert: true }
        }
    }
})

const res = await newCollection.bulkWrite(data);
console.log(res)
Tobok Sitanggang
  • 607
  • 5
  • 15
0

I figured it out. I just needed to add await before the Collection.countDocuments({ name: collectionName }). Like this: await Collection.countDocuments({ name: collectionName }).

Caleb Gross
  • 391
  • 3
  • 12