Donn Felker
Donn Felker

Reputation: 9651

MongooseJS Pre Save Hook with Ref Value

I'm wondering if its possible to get a populated ref value of a Schema field in a pre save hook in MongooseJS?

I'm trying to get a value off of the ref field and I need the ref field (below, that is the User field) so I can grab a timezone off of it.

Schema:

var TopicSchema = new Schema({
    name: {
        type: String,
        default: '',
        required: 'Please fill Topic name',
        trim: true
    },
    user: {
        type: Schema.ObjectId,
        ref: 'User'
    },
    nextNotificationDate: {
        type: Date
    },
    timeOfDay: {                                    // Time of day in seconds starting from 12:00:00 in UTC. 8pm UTC would be 72,000
        type: Number,
        default: 72000,                             // 8pm
        required: 'Please fill in the reminder time'
    }
});

Pre save hook:

/**
 * Hook a pre save method to set the notifications
 */
TopicSchema.pre('save', function(next) {

    var usersTime = moment().tz(this.user.timezone).hours(0).minutes(0).seconds(0).milliseconds(0);  // Reset the time to midnight
    var nextNotifyDate = usersTime.add(1, 'days').seconds(this.timeOfDay);                       // Add a day and set the reminder
    this.nextNotificationDate = nextNotifyDate.utc();

    next();
});

In the save hook above, I'm trying to access this.user.timezone but that field is undefined because this.user only contains an ObjectID.

How can I get this field fully populated so I can use it in the pre save hook?

Thanks

Upvotes: 2

Views: 3033

Answers (1)

EmptyArsenal
EmptyArsenal

Reputation: 7464

You'll need to do another query, but it's not very hard. Population only works on a query, and I don't believe that there is a convenience hook for such cases.

var User = mongoose.model('User');

TopicSchema.pre('save', function(next) {
  var self = this;
  User.findById( self.user, function (err, user) {
    if (err) // Do something
    var usersTime = moment().tz(user.timezone).hours(0).minutes(0).seconds(0).milliseconds(0);  // Reset the time to midnight
    var nextNotifyDate = usersTime.add(1, 'days').seconds(self.timeOfDay);                       // Add a day and set the reminder
    self.nextNotificationDate = nextNotifyDate.utc();

    next();
  });
});

Upvotes: 3

Related Questions