Thanks for your valuable attention, I’m working on MERN stack & trying to do something that’s not working like I am expecting it to be.(Sorry if this turns out to be a repeated question, I’m new to web dev).
Here Goes
1.) There is this ‘Lead’ schema that contains many fields, one particular being ‘status’, when status is changed from ‘stageX’ to ‘stageY’ for a Lead, I want that particular document to update a field ‘stageYdate'(initially null) with the current Date.
2.) I want this to happen regardless of previous existing routes and requests, the field should update depending upon the ‘status’ field, so a model level middleware(not sure if it should be document level instead)
3.) Tried performing operation on a mock schema/model and it isn’t working either.
Making schema and exporting model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ModelMiddlewareSchema = new mongoose.Schema({
stage: {
type: String
},
stageChangeDate:{
type: Date,
}
});
const ModelMiddleware = mongoose.model('ModelMiddleware', ModelMiddlewareSchema);
//Tried using middleware here on "ModelMiddleware", didn't work :(
module.exports = ModelMiddleware;
It was giving error that ModelMiddleware.pre() function is not defined so i had to use it in routes
const ModelMiddleware = require('../models/modelMiddlewareCheck');
const express = require('express');
const router = express.Router();
const logMiddleware = async function(next) {
console.log(`Saving document ${this._id}`);
this.stage = 'stage2'
next();
};
ModelMiddleware.schema.pre('save', logMiddleware);
router.put('/', async (req, res) => {
try {
console.log('req received as', req.body);
const newDoc = new ModelMiddleware();
newDoc.stage = 'stage1';
await newDoc.save();
return res.status(200).send('stage1 created successfully');
} catch (err) {
console.log(err);
res.status(400).send('unsuccessful operation');
}
});
module.exports = router;
Above was mock but i want to do something like this
const stage_initial = this.stage;
const postStageCheck = function(next){
const stage_final = this.stage;
if(stage_initial==='stage1' && stage_final==='stage2'){
this.stageChangeDate = new Date();
this.save()
}
next();
}
ModelMiddleware.post('save', postStageCheck)
2
Answers
The usage of a model middleware is the way to go to permform the check regardless of where the update is coming from.
However, I would use pre instead of post, then you can bundle the stageChangeDate update together with the new status update which would reduce the number of requests to the database.
Overall on the right track but needs a few changes.
You want to modify the document before it’s saved so use
pre
middleware instead ofpost
.post
is executed after the document has been saved so it’s too late to make changes.You need to manually store the previous state if you want to compare it to the new state. You can do this by using a combination of
pre
andpost
.