I'm using mongoose (on node) and I'm trying to add some additional fields to a model on save by using Mongoose middleware.
I'm taking the often-used case of wanting to add a lastmodifiedsince-date. However, I also want to automatically add the name/profilelink of the user which has done the save.
schema.pre('save', function (next) {
this.lasteditby=req.user.name; //how to get to 'req'?
this.lasteditdate = new Date();
next()
})
I'm using passport - http://passportjs.org/ - which results in req.user being present, req
of course being the http-request.
Thanks
EDIT
I've defined pre
on an embedded schema, while I'm calling save
on that parent of the embedded instance. The solution posted below (passing arg as the first param of save) works on the non-embedded case, but not on mine.
You can pass data to your Model.save()
call which will then be passed to your middleware.
// in your route/controller
var item = new Item();
item.save(req, function() { /*a callback is required when passing args*/ });
// in your model
item.pre('save', function (next, req, callback) {
console.log(req);
next(callback);
});
Unfortunately this doesn't work on embedded schemas today (see https://github.com/LearnBoost/mongoose/issues/838). One work around was to attach the property to the parent and then access it within the embedded document:
a = new newModel;
a._saveArg = 'hack';
embedded.pre('save', function (next) {
console.log(this.parent._saveArg);
next();
})
If you really need this feature, I would recommend you re-open the issue that I linked to above.
I know this is really old question, but i am answering it as I spend half a day trying to figure this out. We can pass extra properties as options as following example -
findOneAndUpdate({ '_id': id }, model, { **upsert: true, new: true, customUserId: userId, ipAddress: ipaddress.clientIp** }, function (err, objPersonnel) {
And in pre update and save access as following -
schema.pre('findOneAndUpdate', function (next) {
// this.options.customUserId,
// this.options.ipAddress
});
Thanks,
It can be done with 'request-context'. Step to do:
Install request-context
npm i request-context --save
In your app/server init file:
var express = require('express'),
app = express();
//You awesome code ...
const contextService = require('request-context');
app.use(contextService.middleware('request'));
//Add the middleware
app.all('*', function(req, res, next) {
contextService.set('request.req', req);
next();
})
In you mongoose model:
const contextService = require('request-context');
//Your model define
schema.pre('save', function (next) {
req = contextService.get('request.req');
// your awesome code
next()
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With