In this case I have two models: Protocol and Comment. Each model has a middleware('pre' or 'remove') that calls the other model. Calling the Comment middleware in Comment.js stops at Protocol.findById() because Protocol is an object instead of a model function. Here is the console.log(Protocol) in Comment.js
Protocol : [object Object] Type : object
When const Comment = require('../models/comment') is removed in Protocol.js, then the Comment.js middlware works, and Protocol inside it is seen by the console as follow:
Protocol : function model(doc, fields, skipId) {
model.hooks.execPreSync('createModel', doc);
if (!(this instanceof model)) {
return new model(doc, fields, skipId);
}
Model.call(this, doc, fields, skipId);
} Type : function
I don't understant this behaviour. Moreover, in the other way around, the Protocol.js middleware works fine eventhough Comment.js has const Protocol = require('../models/protocol')
I found out a trick in another topic, which is to replace inside the middleware Protocol.findById() by mongoose.model('Protocol').findById(), but this doesn't explain the issue.
Scripts are presented below. If you need more information please let me know and I'll provide it. Thanks
Protocol.js model & middleware
// Dependencies
const mongoose = require('mongoose')
//Models
//<!---- If Comment is not required here then the Comment Middleware works ---->!
const Comment = require('../models/comment')
//Schema
const protocolSchema = mongoose.Schema({
_id : mongoose.Schema.Types.ObjectId,
title: {
type : String,
required: true
},
comments : [{
type: mongoose.Schema.Types.ObjectId,
ref : 'Comment',
}]
})
//Middleware Hook Call
protocolSchema.pre('remove', async function() {
console.log('Starts Protocol.schema.pre(\'remove\')')
var toBeDeletedProtocol = this
await removeComments()
function removeComments(){
return new Promise ((resolve, reject) => {
console.log('Starts removeComments()')
var deletedComments = []
Comment.find({protocol : toBeDeletedProtocol._id})
.exec()
.then( comments => {
console.log('comments found: ' + comments)
return resolve()
})
.catch(err => {
console.log('Removing comment(s) related to the deleted protocol failed in protocol remove Hook')
return reject(err)
})
})
}
})
//Model Export
module.exports = mongoose.model('Protocol', protocolSchema)
Comment.js model & middleware
//Dependencies
const mongoose = require('mongoose')
//Models
const Protocol = require('../models/protocol')
//Schema
const commentSchema = mongoose.Schema(
{
_id : mongoose.Schema.Types.ObjectId,
content: {
type: String,
required : true
},
protocol : {
type: mongoose.Schema.Types.ObjectId,
ref : 'Protocol',
required : true,
}
}
)
//Middleware Hook Call
commentSchema.pre('save', async function() {
console.log('Starts Comment.schema.pre(\'save\')')
var toBeSavedComment = this
await updateProtocol()
function updateProtocol(){
return new Promise ((resolve, reject) => {
console.log('Starts updateProtocol()')
console.log('toBeSavedComment : '+ toBeSavedComment)
console.log('Protocol : '+ Protocol, 'Type : ' + typeof Protocol)
//<!----- the ERROR occurs here -----!>
Protocol.findById(toBeSavedComment.protocol)
//<!----- Protocol is seen an object instead of a model function -----!>
.exec()
.then( protocol => {
console.log('protocol found : ' + protocol)
return resolve()
})
.catch(err => {
console.log('Error in updateProtocol() in Comment.schema pre \'save\'')
console.log(err)
return reject(err)
})
})
}
})
//Export
module.exports = mongoose.model('Comment', commentSchema
)
Package.json
{
"name": "debug",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.4",
"mongoose": "^5.3.2",
"nodemon": "^1.18.4"
}
}