Search code examples
node.jsmongodbmongoosemiddlewaremongoose-schema

Can I perform mongoose update from post save middleware?


Is it possible to update a document from a post save mongoose middleware? Because it is not working for me.

I have tried in different ways.

Way 1:

QuoteSchema.post('save', function(doc) {
if (doc.quoteString) {
    return;
}
this.quoteString = doc.quoteNumber + "";
this._doc.quoteString = doc.quoteNumber + "";
// update the record with quoteString 
this.update({ _id: this.id }, this, { new: true }, function(err, result) {
    if (!err) {
        console.log("Document Updated");
    }
});
    console.log('post save', doc.quoteString);
});

Way 2: because this contains the saved object id so I tried directly.

QuoteSchema.post('save', function(doc) {
if (doc.quoteString) {
    return;
}
this.quoteString = doc.quoteNumber + "";
this._doc.quoteString = doc.quoteNumber + "";
enter code here
// update the record with quoteString 
this.update(function(err) {
    if (!err) {
        console.log("Document Updated");
    }
});
    console.log('post save', doc.quoteString);
});

Way 3:

QuoteSchema.post('save', function(doc) {
if (doc.quoteString) {
    return;
}
var _quoteString = doc.quoteNumber+"";

this.update({ _id: doc._id }, { $set: { "quoteString": _quoteString } }, function(err) {
    if (!err) {
        console.log("Document Updated");
    }
});
console.log('post save', doc.quoteString);
});

None of these ways works for me.

All I have to do is to update QuoteNumber field after the save. QuoteNumber is being generated from mongoose autoincrement which requires a number field. and I'm also saving a string version of quoteNumber in quoteString field so that in the UI, I can perform regex search in an autocomplete. As regular expression does not work with number type.

any suggestions will be helpful. Thanks.


Solution

  • Just make the autoincrementing field virtual and you don't have to worry about post save hook...

    const QuoteSchema = new Schema(
      {
        quoteNumber: { type: Number },
        quoteString: { type: String },
      },
    );
    
    QuoteSchema.virtual('quote').set(function(value) {
      this.quoteNumber = Number(value);
      this.quoteString = String(value);
    });
    
    QuoteSchema.virtual('quote').get(function() {
      return this.quoteNumber;
    });
    

    Setup:

    QuoteSchema.plugin(autoIncrement.plugin, { model: 'Quote', field: 'quote' });