Inserting proper date into Mongo

3,001 views
Skip to first unread message

Stephen Krichten

unread,
Mar 4, 2014, 4:22:16 PM3/4/14
to sai...@googlegroups.com
I noticed that the auto properties createdAt and updatedAt look like this in Mongo...
ISODate("2014-03-04T19:49:58.812Z")

Which I understand is generally what you want when inserting a date.  However I can't seem to figure out how to get the same datetime datatype inserted via my own model attribute if you set the attribute type to date or datetime, you have to pass in a string, and it gets inserted as a normal string type in mongo.  If I leave out the type validation and use new Date() as the value, it ends up as a string "[object Object]" in mongo.  Can someone tell me how to insert a proper date object like createdAt?

Ambroise Dhenain

unread,
Mar 4, 2014, 4:33:46 PM3/4/14
to Stephen Krichten, sai...@googlegroups.com
I think I remmeber that was somethid called ISODate.

Just took a look and found this:


New ISODate() hould get you what you want.
--
Cordialement,

M. Ambroise Dhenain.

Stephen Krichten

unread,
Mar 4, 2014, 5:10:20 PM3/4/14
to sai...@googlegroups.com, Stephen Krichten
Thanks, but ISODate() is a mongo function, not a javascript function.

Ambroise Dhenain

unread,
Mar 4, 2014, 5:29:15 PM3/4/14
to Stephen Krichten, sai...@googlegroups.com
Yeah, that's right, but it looks like you're using mongo. You won't be able to get the same from javascript, you have to use the mongo function to get an ISODate.

I'm not sure to understand what you're trying to do here. Looks like you want to put an ISODate by yourself in a field of the DB, that's what I understood.

Stephen Krichten

unread,
Mar 4, 2014, 5:49:46 PM3/4/14
to sai...@googlegroups.com, Stephen Krichten
Yes I want the date to be ISODate() ... Then how is Sails doing it?... as I said before, the auto properties createdAt and updatedAt get inserted properly as ISODate, so there should be someway to do it with Sails.  I've tried to follow the code, but its hard to see how they accomplishing this.  I did find that they are initially setting createdAt = new Date(), but then serialization and such occurs and its hard to follow... waterline/query/dql.js line 92

Stephen Krichten

unread,
Mar 4, 2014, 5:54:18 PM3/4/14
to sai...@googlegroups.com, Stephen Krichten

See line 84 there. What happens to createdAt from there... eventually it ends up as ISODate in Mongo, but I can't seem to do the same using a Sails model attribute. 

Ambroise Dhenain

unread,
Mar 4, 2014, 6:28:39 PM3/4/14
to Stephen Krichten, sai...@googlegroups.com


2014-03-04 23:54 GMT+01:00 Stephen Krichten <skri...@narrativemarketing.com>:

See line 84 there. What happens to createdAt from there... eventually it ends up as ISODate in Mongo, but I can't seem to do the same using a Sails model attribute. 



Stephen Krichten

unread,
Mar 4, 2014, 6:48:38 PM3/4/14
to sai...@googlegroups.com, Stephen Krichten
I've already tried new Date().toISOString() as the defaultsTo for my attribute, and it didn't work there... The string has the right format, but it is still just a string datatype in mongo.  I'll try setting it in beforeUpdate but I suspect the same thing will happen.  Here is a text view result...

  "start_date" : "2014-03-04T21:43:05.569Z",
  "createdAt" : ISODate("2014-03-04T21:49:39.993Z"),
  "updatedAt" : ISODate("2014-03-04T21:49:39.993Z"), 

...notice how start_date value is not wrapped in ISODate()

Thanks for looking.  any more ideas :)

Ambroise Dhenain

unread,
Mar 4, 2014, 6:59:51 PM3/4/14
to Stephen Krichten, sai...@googlegroups.com
Ok, well, I thought that worked, I used it in my project and that was fine. I remmeber that was stored the same way than the basic updatedAt/createdAt, if they was a difference I didn't see it!

Hope someone else will be able to help you.

Stephen Krichten

unread,
Mar 4, 2014, 7:05:29 PM3/4/14
to sai...@googlegroups.com, Stephen Krichten
Thank you for the idea of using the lifecycle callback. Setting the value to new Date().toISOString() as your example does just inserted a string, but setting it to just new Date() worked!  Seems odd to have to jump through the extra hoop of the lifecycle callback, so if anyone knows a better way, please let me know.  Thanks!

Cody Stoltman

unread,
Mar 5, 2014, 1:31:00 PM3/5/14
to Stephen Krichten, sai...@googlegroups.com
Stephen,

If you send down an instance of a js date the mongo driver will automatically turn it into an ISODate. So if you have a method like the following it would work:

Model.create({ foo: new Date() }).exec(function(err, user) {
    if(err) return res.serverError(err);
    res.json(user);
});

If you are using the blueprints and don’t have the ability to turn a string into a JS date instance you can still get ISODates by setting schema: true on your model which will serialize your data into the schema format. You can do this on a model like so:

module.exports = {
    schema: true,

    attributes: {
        foo: ‘datetime'
    }
};

Or in the v0.10.x release candidate you can set this in config/models.js
 
-- 
Cody Stoltman

Stephen Krichten

unread,
Mar 5, 2014, 2:11:39 PM3/5/14
to sai...@googlegroups.com, Stephen Krichten
Thanks schema: true was the missing piece of the puzzle for me.

Stephen Krichten

unread,
Mar 6, 2014, 10:20:08 AM3/6/14
to sai...@googlegroups.com, Stephen Krichten
Thanks again, I have a follow up question.  This works great when I call (Collection).create from my conroller and set a parameter value to new Date(whatever).  
 
But I can't get the defaultsTo parameter to work in the model.

for example...

attributes: {
    name: {
      type: 'STRING',
      max: 50,
      required: true
    },
    start_date: {
      type: 'DATETIME',
      defaultsTo: new Date()
    },
    end_date: {
      type: 'DATETIME'
      ,defaultsTo: new Date()
    }
  }

Results in validation errors...

"ValidationError": {
      "start_date": [
        {
          "data": null,
          "message": "Validation error: \"Invalid Date\" is not of type \"datetime\"",
          "rule": "datetime"
        }
      ],
      "end_date": [
        {
          "data": null,
          "message": "Validation error: \"Invalid Date\" is not of type \"datetime\"",
          "rule": "datetime"
        }
      ]
    }

This worked fine before setting schema to true.

Stephen Krichten

unread,
Mar 6, 2014, 10:25:14 AM3/6/14
to sai...@googlegroups.com, Stephen Krichten
Nevermind... I'm pretty sure I am causing the problem from my controller.

Stephen Krichten

unread,
Mar 6, 2014, 10:46:14 AM3/6/14
to sai...@googlegroups.com, Stephen Krichten
I take it back... I fixed my controller but still getting the validation errors.  I was using v0.9.11.  I updated to latest 0.10.0 and it works ok there.

John Tomaselli

unread,
Mar 6, 2014, 3:48:39 PM3/6/14
to sai...@googlegroups.com, Stephen Krichten
Sails 0.9.11, schema : true in model
I always had to use contoller for updates, see the following:
        var params = req.params.all();
        var id = params.id;
        params.Date = new Date(params.Date);
        console.log('id====================================================== ',  id,params.Date )
        var deferredT = Q.defer();
        TWO.update(id, params, function twoUpdated(err,two) {
            if (err) {
                deferredT.reject(err);
                console.log(' err :', err);
            } else
            {
                deferredT.resolve(two);
            }
        });

       deferredT.promise
            .then(function (results) {
                console.log(results);
                if (err) {
                        console.log(' err :', err);
                    }

         });
Reply all
Reply to author
Forward
0 new messages