Thursday, 13 April 2017

Mongoose: save document after post middleware hook changes

I am attempting to execute a function in the Mongoose post middleware every time there is a findOneAndUpdate. I am able to successfully run the function, see the changes however, the changes to not reflect in the document. Below is my mongoose code:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const bcrypt = require("bcrypt-nodejs");


const userSchema = new Schema ({
  name: String,
  email: { type: String, unique: true, lowercase: true },
  password: String,
  points: Number,
  entries: [{
              ask: String,
              askee: String,
              outcome: String,
              category: String,
              timestamp: { type: Date, default: Date.now }
            }]
});

userSchema.pre("save", function(next) {
  const user = this;

  bcrypt.genSalt(10, function(err, salt) {
    if (err) { return next(err); }

    bcrypt.hash(user.password, salt, null, function(err, hash) {
      if (err) { return next(err); }

      user.password = hash;
      next();
    })
  })
});

userSchema.methods.comparePassword = function(candidatePassword, callback) {
  bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
    if (err) { return callback(err); }
    callback(null, isMatch);
  });
};

userSchema.post("findOneAndUpdate", function(result) {
  let totalPoints = 0;

  for (let pos=0; pos < result.entries.length; pos++) {
    if (result.entries[pos].outcome == "accepted") {
      totalPoints = totalPoints + 1;
    } else {
      totalPoints = totalPoints + 10;
    }
  }

  result.points = totalPoints;
  console.log("total points: ", result.points);
  result.save();

});


// Create the model class
const ModelClass = mongoose.model("user", userSchema);

// Export the model
module.exports = ModelClass;

The code in question is the userSchema.post("findOneAndUpdate",...) method. Every time the user submits an entry into the database, I want the points field in the User schema to recalculate. My attempt to save the recalculated points field is result.save(), however the changes are not being reflected in my database. Is there a better way to do this?



via Paul

No comments:

Post a Comment