Home > other >  Mongoose creates the same mongodb collection multiple times in one instance
Mongoose creates the same mongodb collection multiple times in one instance

Time:01-09

I am making a simple todo list application for educational purposes and i am using the custom route functionality,so if the user types a custom route,i am checking if a collection with that name exists in the db and if it does'nt i am creating it,but mongoose creates the same collection many times instead of one.

I am hitting my head on this,do you see something that could trigger this kind of issue in my code ?


const express = require("express")
const mongoose = require("mongoose");
const app = express()
const _ = require("lodash")

app.set('view engine', 'ejs'); 

app.use(express.urlencoded({ extended: true})) 
app.use(express.static('static')); 
app.use('/dep/css', express.static(`${__dirname}/node_modules/bootstrap/dist/css`)) 
app.use('/dep/js', express.static(`${__dirname}/node_modules/bootstrap/dist/js`)) 
app.use('/dep/js', express.static(`${__dirname}/node_modules/particlesjs/dist`)) 
app.use('/dep/js', express.static(`${__dirname}/node_modules/@fortawesome/fontawesome-free/js`))

// --------------------- CONNECTION -----------------------------

mongoose.connect('mongodb://localhost:27017/todoDB');
mongoose.connection.on('connected', function () {
    console.log('Mongoose default connection open to 27017');
});

// -------------------------- MODELS AND SCHEMAS -------------------

const itemsSchema = new mongoose.Schema({
    task: {
        type: String,
        required: [true, "Task cannot be empty !"]
    }
})

const Item = mongoose.model("Item", itemsSchema);

const listSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, "List name cannot be empty !"]
    }, 
    items : [itemsSchema]
})

const List = mongoose.model("List", listSchema);



const dateOptions = {
    day:"numeric",
    weekday:"long",
    month : "long",
    year : "numeric"

}
const currentDay =  new Date().toLocaleDateString("en-US",dateOptions)

// --------------------- GETS ------------------------------------

app.get("/", (req, res) => {

    Item.find((err, items) => {
        if (err) {
            console.log(err);
        } else {
    res.render('list', {
        listName: currentDay,
        newItems:items
    });
    
        }
    })

})

app.get("/:customList", (req, res) => {          //GET A REQUEST TO A CUSTOM ROUTE

const customList = _.capitalize(req.params.customList) //GRAB THE CUSTOM ROUTE STRING

List.findOne( {name:customList},(err,listFound) =>{  //SEARCH IF THE COLLECTION EXISTS
if (err){ console.log(err) }else{

if(listFound){   //IF IT EXISTS RENDER THE VIEW WITH THE COLLECTION DATA

    res.render('list', {
        listName: listFound.name,
        newItems:listFound.items
    });


}else{   //IF ITS NOT THEN CREATE IT WITH THE GIVEN NAME 

    const list = new List({
        name:customList
        })
        list.save()
        res.redirect(`/${customList}`)

        console.log("list created !")
}

}
} )

})

// ------------------- POSTS ------------------------------


app.post("/", (req,res) =>{

let item = new Item({
    task: req.body.newItem
})

if ( req.body.list === currentDay ){

item.save((err)=>{  err?console.log(err):console.log("saved") })
res.redirect("/")

}else{

    List.findOne( {name:req.body.list},(err,listFound) =>{
        if (err){ console.log(err) }else{
        
        listFound.items.push(item)
        listFound.save()
        res.redirect(`/${req.body.list}`)

        }
        } )

}


} )


app.post("/delete", (req,res) =>{

    if ( req.body.list === currentDay ){

        Item.findByIdAndRemove({ _id: req.body.checkbox },(err)=>err?console.log(err):console.log("deleted"))
    res.redirect("/")
        
    }else{

        List.findOneAndUpdate( {name:req.body.list},{ $pull: { items: {_id : req.body.checkbox} } },(err,listFound) =>{

           err ? console.log(err) : res.redirect(`/${req.body.list}`)

            })

    }



})



// -------------------- SERVER --------------------------



const server = app.listen(3000, () => {
    console.log(`Todolist app server is running on port ${server.address().port}`);
})


And this what i am getting from my db server after i create a collection,for example here i create a collection with name "yolo",and when i show my collections... :


> db.lists.find()
{ "_id" : ObjectId("61d9d2c74eff3d67c18430f1"), "name" : "Yolo", "items" : [ ], "__v" : 0 }
{ "_id" : ObjectId("61d9d2c74eff3d67c1843100"), "name" : "Yolo", "items" : [ ], "__v" : 0 }
{ "_id" : ObjectId("61d9d2c74eff3d67c18430f4"), "name" : "Yolo", "items" : [ ], "__v" : 0 }
{ "_id" : ObjectId("61d9d2c74eff3d67c18430f7"), "name" : "Yolo", "items" : [ ], "__v" : 0 }
{ "_id" : ObjectId("61d9d2c74eff3d67c18430fa"), "name" : "Yolo", "items" : [ ], "__v" : 0 }
{ "_id" : ObjectId("61d9d2c74eff3d67c18430fd"), "name" : "Yolo", "items" : [ ], "__v" : 0 }

CodePudding user response:

I think you are confused with the term collection with document, after querying find what you are getting is documents present in the List collection. you can do as below to make the name in the list as unique, however this is not the standard solution, for the property unique you might want to check the documentation here

const listSchema = new mongoose.Schema({
name: {
    type: String,
    required: [true, "List name cannot be empty !"],
    unique: true
}, 
items : [itemsSchema]

})

const List = mongoose.model("List", listSchema);

CodePudding user response:

The save() function is asynchronous. When you call redirect immediately after calling save, you have a race condition, and it will continue to loop and call save followed by redirect until one of the save calls actually completes.

To fix this, move the redirect call to a callback function passed to save

  •  Tags:  
  • Related