Skip to content

pre.remove middleware of objects in array are never called (with 5.0.9) #6224

Closed
@jmcollin78

Description

@jmcollin78

Do you want to request a feature or report a bug?
A bug

What is the current behavior?
I create an Embedded object named FileSpace into an array of object named Space. When removing FileSpace, pre remove middleware is never call (but pre validate middleware is called)

If the current behavior is a bug, please provide the steps to reproduce.

Here is a repro code:

'use strict';

var mongoose = require('mongoose'),
	Schema = mongoose.Schema;

mongoose.set('debug', true);


/**
 *  A file
 */
var FileSpaceSchema = new Schema({
	fileKey: {
		type: String,
		required: true
	}
});

// Normally called 
FileSpaceSchema.pre('validate', function (next) {
	console.log('Calling FileSpace.pre.validate me="%s"', this.fileKey);
	next();
});

// Never called !
FileSpaceSchema.pre('remove', function(next) {
	console.log(' !!! Calling FileSpace.pre.remove fileKey="%s"', this.fileKey);
	next();
});

let FileSpace = mongoose.model('FileSpace', FileSpaceSchema);

/**
 * A space containing an array of files
 */
var SpaceDocSchema = new Schema({
	label: {
		type: 'string',
		required: true
	},
	files: [FileSpaceSchema]
});

SpaceDocSchema.pre('validate', function (next) {
	console.log('Calling SpaceDocSchema.preValidate hook spaceDoc is "%s"', this.label);
	next();
});

SpaceDocSchema.pre('remove', function (next) {
	console.log('Calling Space.post.remove spaceDoc is "%s"', this.label);
	next();
});

let SpaceDoc = mongoose.model('SpaceDoc', SpaceDocSchema);

console.log('--> Starting');

console.log('--> Creating a space');
let space = new SpaceDoc({
	label: 'The SpaceDoc'
}),
	removedFile;

// connect to mongo
mongoose.connect('mongodb://mongodbsrv/clouderialTestDB?w=1&j=true');

mongoose.connection.on('open', () => {
	console.log('Connection to MongoDB is effective');
	
	space.save()
		.then((s) => {
			space = s;
			console.log('Created space is "%s"', s.label);
			
			console.log('--> Creating a FileSpace');
			return new FileSpace({fileKey : 'fileSpace', spaceLabel:'The space label'}).save();
		})
		.then((fs) => {
			console.log('Created FileSpace is "%s"', fs.fileKey);
			console.log('--> Add fileSpace into SpaceDoc.files');
			space.files.push(fs);
			space.markModified('files');
			return space.save();
		})
		.then((s) => {
			space = s;
			console.log('Updated space is "%s", nbFiles="%d"', space.label, space.files.length);
			console.log('--> Remove fileSpace from space');
			removedFile = space.files[0];
			space.files.splice(0, 1);
//			space.files = [];
			space.markModified('files');
			console.log('--> Update space without file');
			return space.save();
		})
		.then((s) => {
			space = s;
			console.log('Updated space is "%s", nbFiles="%d"', space.label, space.files.length);
			console.log('--> Remove fileSpace');
			return removedFile.remove();
		})
		.then(() => {
			console.log('--> Should see the call to pre.remove of FileSpace');
			console.log('--> Remove space');
			return space.remove();
		})
		.catch(console.error);
});

setTimeout(() => {
	console.log('--> Close MongoDB connection');
	mongoose.connection.close();
}, 3000);

The output is the following:

$ npm start

> test@0.0.1 start /datas/cld-apps/test
> NODE_PATH=/home/vagrant/cld-apps/node_modules:. TZ=Europe/Paris node test.js

--> Starting
--> Creating a space
Connection to MongoDB is effective
Calling SpaceDocSchema.preValidate hook spaceDoc is "The SpaceDoc"
Mongoose: spacedocs.insert({ label: 'The SpaceDoc', files: [], _id: ObjectId("5aa18e47f13311778fdc3beb"), __v: 0 })
Created space is "The SpaceDoc"
--> Creating a FileSpace
Calling FileSpace.pre.validate me="fileSpace"
Mongoose: filespaces.insert({ fileKey: 'fileSpace', _id: ObjectId("5aa18e47f13311778fdc3bec"), __v: 0 })
Created FileSpace is "fileSpace"
--> Add fileSpace into SpaceDoc.files
Calling SpaceDocSchema.preValidate hook spaceDoc is "The SpaceDoc"
Calling FileSpace.pre.validate me="fileSpace"
Mongoose: spacedocs.update({ _id: ObjectId("5aa18e47f13311778fdc3beb"), __v: 0 }, { '$set': { files: [ { fileKey: 'fileSpace', _id: ObjectId("5aa18e47f13311778fdc3bec"), __v: 0 } ] }, '$inc': { __v: 1 } })
Updated space is "The SpaceDoc", nbFiles="1"
--> Remove fileSpace from space
--> Update space without file
Calling SpaceDocSchema.preValidate hook spaceDoc is "The SpaceDoc"
Mongoose: spacedocs.update({ _id: ObjectId("5aa18e47f13311778fdc3beb"), __v: 1 }, { '$set': { files: [] }, '$inc': { __v: 1 } })
Updated space is "The SpaceDoc", nbFiles="0"
--> Remove fileSpace
--> Should see the call to pre.remove of FileSpace
--> Remove space
Calling Space.post.remove spaceDoc is "The SpaceDoc"
Mongoose: spacedocs.remove({ _id: ObjectId("5aa18e47f13311778fdc3beb") }, {})
--> Close MongoDB connection

What is the expected behavior?
We should see the log line:

!!! Calling FileSpace.pre.remove fileKey

Please mention your node.js, mongoose and MongoDB version.
Node 9.5.0, Mongoose 5.0.9, MongoDB 3.6.3, Mongo driver: 3.0.3

EDIT: try with 5.0.9.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions