I'm trying to define a folder schema in Mongoose. For each folder, I'd like to store a reference to the parent folder, as well as an array of child subfolders (to make traversal in either direction easy):
var folderSchema = new mongoose.Schema({
name: String,
parent: { type: Schema.Types.ObjectId, ref: 'Folder' },
subfolders: [{ type: Schema.Types.ObjectId, ref: 'Folder' }],
});
When creating a folder, I want to be able to only specify the parent folder, and then have a pre-save hook take care of adding the subfolder to the parent folder's subfolders array. This part works fine:
folderSchema.pre('save', function (next) {
var self = this;
// If creating a subfolder, then add the subfolder to
// the parent folder's "subfolders" array
if (this.parent) {
Folder.findById(this.parent, function (err, parent) {
if (err) return next(err);
if (parent) {
parent.subfolders.push(self);
return parent.save(next);
}
return next();
});
} else {
next();
}
});
Also, when deleting a subfolder, I would like to use a pre-remove hook to automatically remove the subfolder from the parent folder's subfolders array. Unfortunately, I can't get this part to work:
folderSchema.pre('remove', function (next) {
var self = this;
// If deleting a subfolder, then remove it from the parent
// folder's "subfolders" array
//
// (Note: it would also be a good idea to recursively remove
// all subfolders here, but I'm not attempting this yet.)
if (this.parent) {
Folder.findById(this.parent, function (err, parent) {
if (err) return next(err);
if (parent) {
parent.subfolders.id(self._id).remove(); // TypeError: Object 53a64349741d1ae82274c9a2 has no method 'id'
return parent.save(next);
}
return next();
});
} else {
next();
}
});
The line that's erroring out is this one:
parent.subfolders.id(self._id).remove();
It results in this error:
TypeError: Object 53a64349741d1ae82274c9a2 has no method 'id'
at Promise.<anonymous> (C:\Users\serg\temp\mongoose\folders\index.js:53:35)
at Promise.<anonymous> (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\node_modules\mpromise\lib\promise.js:177:8)
at Promise.EventEmitter.emit (events.js:95:17)
at Promise.emit (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\node_modules\mpromise\lib\promise.js:84:38)
at Promise.fulfill (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\node_modules\mpromise\lib\promise.js:97:20)
at C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\lib\query.js:1393:13
at model.Document.init (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\lib\document.js:250:11)
at completeOne (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\lib\query.js:1391:10)
at Object.cb (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\lib\query.js:1150:11)
at Object._onImmediate (C:\Users\serg\temp\mongoose\folders\node_modules\mongoose\node_modules\mquery\lib\utils.js:137:16)
What I was trying to do is use the MongooseDocumentArray#id method to remove the sub document, as shown in the example on the Sub Docs page of Mongoose's documentation. However, it looks like that method is not available, and I'm not sure why that is. Did I define the schema incorrectly? Is the id method not available from within middleware? Or am I simply not using it correctly?