davidpauljunior
davidpauljunior

Reputation: 8338

Adding a new property to mongo after 'save' in Keystone

I recently found out how to change the value of an existing property and saving it to the mongo database when using Keystone JS (How to alter a value before storing it to the database in Keystone JS).

Now I need to add a new property and save it to the database during the same pre('save') phase.

The aims is to say, if the result (existing property) of a game is 'Won', then add a new property 'won' which is a boolean (true). If it matters, the reason I want this is because in a handlebars template I want to say {{#if won}}class="success"{{/if}}

Game.schema.pre('save', function(next) {
    if (this.isModified('result')) {
        if (this.result === 'Won') {
            this.won = true;
        }
    }
    next()
});

But nothing happens. I read that you can't add properties unless they've been set in the schema. So I tried adding Game.schema.set('won', false); above that, but still nothing.

Is there a simple way to do this?

Upvotes: 0

Views: 237

Answers (1)

Steve Holgado
Steve Holgado

Reputation: 12089

You could look at Mongoose virtuals which are properties that you can get and set but that do not get persisted to the database:

Game.schema.virtual('won').get(function() {
  return this.result === 'Won'
})

http://mongoosejs.com/docs/guide.html#virtuals

If you just want to use it in your template then you could also set a specific property on locals in your view.

Perhaps something like this:

...

exports = module.exports = function(req, res) {

  var view = new keystone.View(req, res)

  var locals = res.locals

  locals.games = []

  view.on('init', function(next) {

    var query = {} // Add query here

    Game.model.find(query).exec(function(err, games) {

      // Handle error

      games.forEach(function(game) {
        game.won = game.result === 'Won'
      })

      locals.games = games

    })

  })

}

...

Upvotes: 1

Related Questions