Mongoose: How to make the global schema settings working with the local settings?

Zhiguang Chen
2 min readDec 12, 2020

--

https://mongoosejs.com/docs/plugins.html

This document introduces a way to register global schema settings by registering global plugins, but it does not mention the situation when there are both global settings and local settings exist, such as what is the registration order? how to chain the functions? etc. Here is my solution, but not sure if it meets the best practice.

For example, here I have a memberSchema with a toJSON setting to transform avatar object to avatar.file and return this string, also have a setting: virtuals:true

const memberSchema = new Schema({
avatar: {
type: imageSchema,
},
});
memberSchema.set('toJSON', {
virtuals:true,
transform: (document, returnedObject) => {
returnedObject.avatar = returnedObject.avatar?.file;
},
});

So, this is the way I register a global schema setting to delete _id and __v but also keep the settings from memberSchema

// typescriptmongoose.plugin((schema: Schema) => {
// Some other features, such as:
// schema.pre('remove', backup);
set_toJSON(schema);
});
const set_toJSON = (schema: Schema) => {
// Clone the setting from schemas
const settings = { ...schema.get('toJSON') };
// Abstract transform function
const transform = settings.transform;
delete settings.transform;
schema.set('toJSON', {
// It will be overridden
virtuals: false,
transform: (document, returnedObject) => {
delete returnedObject._id;
delete returnedObject.__v;
//Execute the transform function from schemas such as memberSchema
transform && transform(document, returnedObject);
},
// Attach the other settings, such as virtuals:true from memberSchema in this example.
...settings,
});
};

Now both transforms are working fine, also the local setting virtual:true overrides the global one!

Please leave a comment if you have any other solutions, or maybe there is even an official interface to use? Thanks!

--

--

Zhiguang Chen

Full-stack Web Developer: Flutter, Node.js, Angular, ReactNative, Laravel