skip to Main Content

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


  1. 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.

    const schema = new Schema({ /* ... */ });
    schema.pre('save', function(next) {
      const currentStatus = this.status
    
      if (this.isModified('status') {
        const newStatus = this.status
    
        if (currentStatus === 'x' && newStatus === 'y') {
          this.stageChangeDate = new Date()
        }
      }
    
      next();
    });
    
    Login or Signup to reply.
  2. 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 of post. 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 and post.

    // Pre-save middleware to store the stage
    ModelMiddlewareSchema.pre('save', function(next) {
      // Store the initial stage on the document
      this._initialStage = this.stage;
      next();
    });
    
    // Post-save middleware to check for change and update
    ModelMiddlewareSchema.post('save', async function(doc) {
      if (this._initialStage === 'stage1' && this.stage === 'stage2') {
        // Update the stageChangeDate field
        this.stageChangeDate = new Date();
        // Save the updated document
        await this.save();
      }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search