mongodbdatemeteormeteor-autoform

Meteor new Date() invalid with mongodb 3.0.1 and autoform/simple schema


I've trouble dealing with a type: Date into SimpleSchema having a defaultValue. In mongodb (3.0.1), the date entry have the time the meteor thread have been launch. The expected behaviour is to have "date" the insertion date of the object on the server.

lib/schema.js

Schema.DateCol = new SimpleSchema({
  date: {
    type: Date,
    defaultValue: new Date()
  },
  dateModified: {
    type: Date,
    autoValue: function () { return new Date(); }
  }
});

client/home.html

    {{> quickForm id="test" schema="Schema.DateCol" collection="DateCol" type="insert" }}

Into the mongo, after inserting two objects:

Object 1

{
  "_id": "PuME9jWwJJiw9diSC",
  "date": new Date(1432117722634),
  "dateModified": new Date(1432117850366)
}

Object 2:

{
  "_id": "qqHqkN4YapWDsFhxx",
  "date": new Date(1432117722634),
  "dateModified": new Date(1432117890380)
}

You'll fin enclose a repository Github with the error, using MongoDB 3.0.1 (I haven't this error on MongoDB 2.4): https://github.com/JVercout/meteor-defaultValue-date-errored

Any ideas?


Solution

  • The problem is that the new Date() expression is evaluated once when the code creating the schema is run. That value is then used as the defaultValue. There is no difference between:

    var x = new SimpleSchema({
      date: {defaultValue: new Date(), ...}
    });
    

    and

    var defaultDate = new Date();
    var x = new SimpleSchema({
      date: {defaultValue: defaultDate, ...}
    });
    

    It looks like you'll need an autoValue, since it doesn't look like you can use a function for defaultValue. The Collection2 documentation actually has an example of using autoValue for a "created at" field. It depends on fields added by Collection2 but I saw in your git repo that you're using that.

    // Force value to be current date (on server) upon insert
    // and prevent updates thereafter.
    createdAt: {
      type: Date,
      autoValue: function() {
        if (this.isInsert) {
          return new Date();
        } else if (this.isUpsert) {
          return {$setOnInsert: new Date()};
        } else {
          this.unset();
        }
      }
    }