I have the following Schema and Model:
const userSchema = new mongoose.Schema({
name: String,
})
const UserModel = mongoose.model('User', userSchema, 'users')
and I have written the following express middleware, which simply takes one argument, awaits that argument, set the returned value from that awaiting job to the req object on a property called gottenDocs, (i.e.: req.gottenDocs)
function getDocumentsMw(query) {
return async (req, res, next) => {
const dbRes = await query
req.gottenDocs = dbRes
next()
}
}
and I have the following route:
app.get(
'/users',
getDocumentsMw(UserModel.find({})),
(req, res, next) => {
const gottenDoc = req.gottenDocs
res.status(200).json({
status: 'success',
data: gottenDoc,
})
})
That’s all I have, now, when I request [ GET " /users " ] I recieve the following response which is great, and nothing is wrong:
{
"status": "success",
"data": []
}
but, the weird thing is when I request this route again, it throws this error:
MongooseError: Query was already executed: User.find({})
What could be the problem? is it a bug in Nodejs? which could be hmmm, something like, that it is not removing the function call from the call stack after the response has been sent?
any help appreciated.
>Solution :
The problem is on this line
getDocumentsMw(UserModel.find({})),
Here you create a query once the application start, because of that the query is created once but executed multiple times.
You may need to refactor your code to something like that
getDocumentsMw(() => UserModel.find({})),
Now you are passing a function and not a query. The function creates a query, aka factory. Next step is to refactor getDocumetnsMw to call the function to create a query when it needs to do something with it.
function getDocumentsMw(queryFactory) {
return async (req, res, next) => {
const dbRes = await queryFactory()
req.gottenDocs = dbRes
next()
}
}
