Mongoose: Preserve isNew state in post save

Created on 7 May 2013  ·  14Comments  ·  Source: Automattic/mongoose

It still important to know if the object was new in the post save middleware right now i believe it is set to false it should be set to false after the post save.

new feature

Most helpful comment

schema.pre('save', function (next) {
  this.wasNew = this.isNew;
  next();
})

schema.post('save', function () {
  if (this.wasNew) {
     // ...
  }
})

All 14 comments

schema.pre('save', function (next) {
  this.wasNew = this.isNew;
  next();
})

schema.post('save', function () {
  if (this.wasNew) {
     // ...
  }
})

Does this cause the wasNew property to persist?

not unless you add it to your schema

Hi,

I'm trying to use this in a piece of code that I have, but I don't know why this is not working. In pre-save wasNew is created and is true. But in post-save, this flag is not defined (so I get an undefined).

There is something I'm doing wrong? It's like if the scope of _this_ is not preserved (or binded) between both functions.

I've tried to mongoose versions, one installed from npm ('3.9.8-pre') and the other one builded from this repo... Do someone have any suggestions?

I've understood that my Schema doesn't need to contain a _wasNew_ field, is that right?

Thanks in advance!

Code:

module.exports = function (schema) {

    log.info("Inside functions");

    schema.pre('save', function (next) {
        log.info('pre saving...');

        this.wasNew = this.isNew;
        var self = this;
        if (self.isNew) {
            self.information.token = require('crypto').randomBytes(48).toString('hex');
            self.profile.name = (self.email.split("@"))[0];
        }
        next();
    });

    schema.post('save', function (doc) {
        log.info('post saving...', this);

        if (this.wasNew) {
            log.info("Sending email");
            mailingService.welcome(this.email);
        }

        var bond = {
            "name": doc.profile.name,
            "owner": doc._id
        };

        log.info(bond);

        dbHelper.createBond(bond);
    });
};

Hi again, I've changed the _this.wasNew_ to _doc.wasNew_ and now is working successfully! And the field is not stored in the document, as it was required.

This is correct, isn't it?

Thanks!

Yep :)

Guys, this tweak should really be added to the current branch as a default for every schema.

Any reason why wasNew shouldn't be built in? Should we add it to mongoose?

Reasonable idea, we'll consider it for later 5.x releases.

Hello everybody !

Any update for this built in feature ?

wasNew is not present on mongoose _(5.4.19)_ when I trie to save a new document

@darkterra wasNew is not there, you need to create it inside pre and than can use inside post as mentioned in above comment https://github.com/Automattic/mongoose/issues/1474#issuecomment-17669982

@thakurinbox, thank you for your response.

If I understand correctly the question of the original post is to "preserve isNew _in the postSave hook_", then @emanuelecasadio, @lbstr and @vkarpov15 seems to say that it would be nice to have built in this data in" postSave " _ (whether it is the property 'isNew' or 'wasNew') _.

I have not 'isNew' or 'wasNew', so I wondered if the 'isNew' property no longer exists and will be replaced by the future by 'wasNew'?

_Little peace of code:_

'use strict';

const mongoose = require('mongoose');  // v5.4.19

const connect = mongoose.connect('mongodb://localhost/test_mongoose', { useNewUrlParser: true });
console.log('mongoose connect: ', connect);

connect.then(connectionObject => {
  const Schema = mongoose.Schema;

  const BlogPost = new Schema({
    title: String,
    body: String,
    date: Date
  });

  BlogPost.pre('save', function(next, doc, err) {
    console.log('pre: this: ', this);
    console.log('pre: doc: ', doc);
    next();
  });

  BlogPost.post('save', function(doc, next) {
    console.log('post: this: ', this);
    console.log('post: doc: ', doc);
    next();
  });

  const BlogModel = mongoose.model('BlogPost', BlogPost);


  const newBlogPost = new BlogModel({
    title: 'This is a test',
    body: 'This is the BEST POST ever !!!!!',
    date: new Date()
  });

  console.log('newBlogPost: ', newBlogPost);

  newBlogPost.save((err, doc) => {
    if (err) {
      console.error(err);
    }
    else
    {
      console.log('callback SAVE: ', doc);
      console.log('Post SAVED :)')
    }
  });
})

_And no isNew or wasNew there:_

mongoose connect:  Promise { <pending> }

newBlogPost:  { _id: 5c90aeb34f000a254ed2b6f7,
  title: 'This is a test',
  body: 'This is the BEST POST ever !!!!!',
  date: 2019-03-19T08:56:19.011Z }

pre: this:  { _id: 5c90aeb34f000a254ed2b6f7,
  title: 'This is a test',
  body: 'This is the BEST POST ever !!!!!',
  date: 2019-03-19T08:56:19.011Z }

pre: doc:  SaveOptions {}

post: this:  { _id: 5c90aeb34f000a254ed2b6f7,
  title: 'This is a test',
  body: 'This is the BEST POST ever !!!!!',
  date: 2019-03-19T08:56:19.011Z,
  __v: 0 }

post: doc:  { _id: 5c90aeb34f000a254ed2b6f7,
  title: 'This is a test',
  body: 'This is the BEST POST ever !!!!!',
  date: 2019-03-19T08:56:19.011Z,
  __v: 0 }

callback SAVE:  { _id: 5c90aeb34f000a254ed2b6f7,
  title: 'This is a test',
  body: 'This is the BEST POST ever !!!!!',
  date: 2019-03-19T08:56:19.011Z,
  __v: 0 }

Post SAVED :)

Ok, obviously, the console can not seem to show me the other property of the object as well as these methods, but I try to call "this.isNew" and "this.isModified ()" in the preSave and I have something that appears in the console ...

  BlogPost.pre('save', function(next, doc, err) {
    console.log('pre: this: ', this);
    console.log('pre: doc: ', doc);
    console.log('pre: this.isNew: ', this.isNew); // true
    console.log('pre: this.isModified(): ', this.isModified()); // true

    this.wasNew = this.isNew;

    console.log('pre: this.wasNew: ', this.wasNew); // true
    next();
  });

So, I confirm that the trick in this issue works well. On the other hand, in the past, I am sure that the console could display the functions and other properties of the object over defined by Mongoose.

No updates on this feature yet, that's why this issue is still open :+1: . Manually setting wasNew in pre save is the way to go for now

Was this page helpful?
0 / 5 - 0 ratings