Keeping MongoDB attributes in sync can be tricky. But there’s more than one way to skin a cat!

Today I was attempting to use Mongoose middleware — pre('findOneAndUpdate') — to update the icon attribute of a document calledMeeting. My updated icon value depended on the pre-existing value of the yearlymeeting attribute in the Meeting record (see below).
In Mongoose, pre and post save() hooks are executed on save(), but not on update(), so I was unable to access the original document at all. Yet it was essential for this operation that I have access to the stored document.
For example, I am able to accomplish my purpose on pre('save'), like so:
meetingSchema.pre('save', function(next) {
const yearlymeetingSlug = this.yearlymeeting[0].toLowerCase().replace(/[^A-z0-9]/g, '');
this.icon = `${yearlymeetingSlug}.png`
next();
});What I would like to be able to do is something like this:
meetingSchema.pre('findOneAndUpdate', function(next) {
const yearlymeetingSlug = originalDocument.yearlymeeting[0].toLowerCase().replace(/[^A-z0-9]/g, '');
this.icon = `${yearlymeetingSlug}.png`
next();
});Unfortunately for me,this in pre('findOneAndUpdate') refers to the query, rather than the stored document itself. This means that the information I needed is located only in the database, where I didn’t have access to it.
After quite a bit of brainstorming, research, and even posting the problem on StackOverflow, I eventually concluded that the best way to solve this problem was to give up trying to update the icon attribute from Mongoose middleware in the schema. Instead, I would perform the operation from a place where I knew I would have access to the existing document — in the controller!
Here’s the code I ended up using to solve my problem:
exports.updateMeeting = async (req, res) => {
const _id = req.params.id
let meeting = await Meeting.findOneAndUpdate({ _id }, req.body, {
new: true,
runValidators: true
});
/* New Code: */
const yearlymeetingSlug = meeting.yearlymeeting[0].toLowerCase().replace(/[^A-z0-9]/g, '');
meeting.icon = `${yearlymeetingSlug}.png`;
meeting.save();
req.flash('success', 'meeting successfully updated!');
res.redirect(`/meetings/${meeting.slug}`);
};What do you think about this solution? Was moving the operation over into the controller, rather than the schema, the right way to go about it? How would you have solved this problem?
