Sharing data between Mongoose middleware methods pre save and post save

1,632 views
Skip to first unread message

justin hyland

unread,
Sep 23, 2016, 2:05:55 PM9/23/16
to Mongoose Node.JS ODM
I'm using Mongoose (which is awesome btw!) in my current NodeJS projects, and I have a MDB collection thats going to store the changes of documents in a different collection (Basically a changelog storing what was modified)

How I'm trying to accomplish that is create a function that stores a JSON version of the document, which is done via the pre('save') hook. Then create another hook, which gets executed via post('save'), to compare the data stored in pre('save'), and compare it with the documents new data.

Heres what I have thus far:

var origDocument
var testVar = 'Goodbye World'

module.exports = ( schema, options ) => {
    schema
.pre( 'save', function( next ) {
       
// Store the original value of the documents attrCache.Description value
        origDocument
= this.toJSON().attrCache.Description


       
// Change the testVar value to see if the change is reflected in post(save)
        testVar
= 'Hello World'
       
next()
   
} )

    schema
.post( 'save', function(  ) {
       
// Attempt to compare the documents previous value of attrCache.Description, with the new value
        console
.log("BEFORE:", origDocument)
        console
.log("AFTER:", this.toJSON().attrCache.Description)
       
       
// Both of the above values are the same! >.<

        console
.log('post(save):',testVar) // result: post(save):Hello World
       
// But the above works just fine..
   
} )
}

I originally didn't think this would work. To test that the two hooks get executed in the same scope, I created a test variable at the top of the page called `testVar` with some arbitrary value, then in the post(save) hook, retrieved the testVar, and the value modification of that variable was seen in the post save hook.

So from there, I just stored the value of this.toJSON() in a variable, then in the post(save) hook, I am trying to retrieve the cached version of this document, and compare it to this.toJSON(). However, it doesn't look like the document from the pre(save) doesn't hold the pre-modified data, it somehow has the value of the document after it was updated.

So why can I update the value of testVar from within a pre(save) hook, and that change is reflected from a `post(save)` hook function, but I cant do the same thing with the document itself?

Is what im trying to do here even possible? If so, what am I doing wrong? If not - How can I accomplish this?

Thank you

P.S.

I tried to run the data through JSON.stringify() before saving it in memory via the pre(save) hook, then do the same in the post(save), like so:

var origDocument


module.exports = ( schema, options ) => {
    schema
.pre( 'save', function( next ) {
     
        origDocument
= JSON.stringify( this.toJSON().attributes[1].value )

       
// Should store and output the CURRENT value as it was before the
       
// document update... but it displays the NEW value somehow
        console
.log( '[MIDDLEWARE] ORIGINAL value:', origDocument )

       
next()
   
} )

    schema
.post( 'save', function(  ) {
       
var newDocument = JSON.stringify(this.toJSON().attributes[1].value)

        console
.log( '[MIDDLEWARE] UPDATED value:', newDocument )
   
} )
}


And here's the script that updates the mongoose document:

Asset.getAsset( '56d0819b655baf4a4a7f9cad' )
   
.then( assetDoc => {
       
// Display original value of attribute
        console
.log('[QUERY] ORIGINAL value:', assetDoc.attributes[1].value)

       
var updateNum = parseInt( assetDoc.__v )+1
        assetDoc
.attr('Description').set('Revision: ' + updateNum )

       
return assetDoc.save()
   
} )
   
.then(data => {
       
// Display the new value of the attribute
        console
.log('[QUERY] UPDATED value:', data.attributes[1].value)
       
//console.log('DONE')
   
})
   
.catch( err => console.error( 'ERROR:',err ) )


Heres the console output when I run the new script:

[QUERY] ORIGINAL value: Revision: 67
[MIDDLEWARE] ORIGINAL value: "Revision: 68"
[MIDDLEWARE] UPDATED value: "Revision: 68"
[QUERY] UPDATED value: Revision: 68

As you can see, the [QUERY] ORIGINAL value and the [QUERY] UPDATED values show that there was an update. But the [MIDDLEWARE] original/updated values are still the same... So im still stuck as to why

Reply all
Reply to author
Forward
0 new messages