Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve isNew state in post save #1474

Closed
greggreenhaw opened this issue May 7, 2013 · 19 comments
Closed

Preserve isNew state in post save #1474

greggreenhaw opened this issue May 7, 2013 · 19 comments
Labels
help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary

Comments

@greggreenhaw
Copy link

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.

@aheckmann
Copy link
Collaborator

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

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

@danscan
Copy link

danscan commented Apr 8, 2014

Does this cause the wasNew property to persist?

@aheckmann
Copy link
Collaborator

not unless you add it to your schema

@GerardSoleCa
Copy link

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);
    });
};

@GerardSoleCa
Copy link

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!

@vkarpov15
Copy link
Collaborator

Yep :)

@emanuelecasadio
Copy link

emanuelecasadio commented Jul 26, 2017

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

@lbstr
Copy link

lbstr commented Jun 14, 2018

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

@vkarpov15 vkarpov15 added new feature This change adds new functionality, like a new method or class and removed bug? labels Jun 18, 2018
@vkarpov15 vkarpov15 reopened this Jun 18, 2018
@vkarpov15 vkarpov15 added this to the 5.x Unprioritized milestone Jun 18, 2018
@vkarpov15
Copy link
Collaborator

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

@darkterra
Copy link

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

@thakurinbox
Copy link

@darkterra wasNew is not there, you need to create it inside pre and than can use inside post as mentioned in above comment #1474 (comment)

@darkterra
Copy link

@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 :)

@darkterra
Copy link

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.

@vkarpov15
Copy link
Collaborator

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

@vkarpov15 vkarpov15 removed this from the 5.x Unprioritized milestone May 18, 2021
@vkarpov15 vkarpov15 added help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary and removed new feature This change adds new functionality, like a new method or class labels May 18, 2021
@SailokChinta
Copy link

@vkarpov15 can we expect whether this feature would be added in further new releases? This seems to be a pretty common issue, isn't it?

@vkarpov15
Copy link
Collaborator

@SailokChinta we don't plan on adding this any time in the near future. Adding support for wasNew via a global plugin is a one-liner, so not a priority for now.

@Konijima
Copy link

Konijima commented May 6, 2022

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

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

This would be an ok solution if it didn't trigger an error with Typescript...
It's 2022 and no fix/update for this yet?

Using this is very ugly especially when it's everywhere

schema.pre('save', async function () {
    // @ts-ignore
    this.wasNew = this.isNew
})

schema.post('save', async function () {
    // @ts-ignore
    if (this.wasNew) {
...

@Uzlopak
Copy link
Collaborator

Uzlopak commented May 6, 2022

Would you please create a new issue as it is a different scope bug (typescript) and provide a mcve?

I would then try to fix the issue.

@vkarpov15
Copy link
Collaborator

@Konijima you can always just use this.$locals.wasNew instead, that should appease TypeScript.

@Automattic Automattic locked and limited conversation to collaborators May 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary
Projects
None yet
Development

No branches or pull requests