Search code examples
mongoosemongoose-schema

schema.post('find') and schema.post('findOne')


app.js

Match.find({}).lean().exec(function(err, matches) {});
Match.findById(id).lean().exec(function(err, match) {});

I use both of these queries in different routes.

Match-Model:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var messageSchema = new Schema({
    // ...
    message: {type: String, required: true},
}, {
    timestamps: true
});

var matchSchema = new Schema({
    // ...
    messages: [messageSchema]
}, {
    timestamps: true
});

matchSchema.post('find', function(result) {
    result.forEach(function(chat) {
        chat.messages.forEach(function(message) {
            message.createdAt = new Date(message.createdAt).getTime();
            message.updatedAt = new Date(message.updatedAt).getTime();
        });
    });
});

matchSchema.post('findOne', function(result) {
    if (result !== null) {
        result.messages.forEach(function(message) {
            message.createdAt = new Date(message.createdAt).getTime();
            message.updatedAt = new Date(message.updatedAt).getTime();
        });
    }
});

var Match = mongoose.model('Match', matchSchema);

module.exports = Match;

Parsing the default date format (like 2016-05-19T13:29:07.731Z) in Java (which I use on client side) is a pain, that's why I instead overwrite it with the unix timestamp, which is easy to format in Java. The problem with this is, I have duplicate code (message.createdAt = ... and message.updatedAt ..) for find and findOne. Is there a hook which triggers for both queries find and findByID? So I only have to write my code once? Because find won't trigger for findById.


Solution

  • Since both hooks already look very similar, you could combine them into one function that gets used by all (similar) hooks:

    function processResult(result) {
      if (result) {
        if (! Array.isArray(result)) {
          result = [ result ];
        }
        result.forEach(function(chat) {
            chat.messages.forEach(function(message) {
                message.createdAt = new Date(message.createdAt).getTime();
                message.updatedAt = new Date(message.updatedAt).getTime();
            });
        });
      }
    }
    
    matchSchema.post('find',    processResult);
    matchSchema.post('findOne', processResult);
    

    I believe that findOne will trigger for findById, so that should be covered as well.