Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inserting a momentjs object in Meteor Collection

I have a simple Meteor collection and I am trying to insert a document that has a momentjs property into it. So I do:

docId = Col.insert({m: moment()});

However, when I try to get this document back with

doc = Col.findOne({_id: docId})

I get "Invalid date" for doc.m like so:

Object {_id: "wnHzTpHHxMSyMxmu3", m: "Invalid date"}

Anyone?!

like image 551
babbata Avatar asked Jan 05 '14 18:01

babbata


2 Answers

I strongly recommend storing dates as Date objects and using moment to format them after they are fetched. For example:

Posts.insert({message: 'hello', createdAt: new Date});

Then later when you want to display the date:

var date = Posts.findOne().createdAt;
moment(date).format('MMMM DD, YYYY');
like image 105
David Weldon Avatar answered Sep 23 '22 05:09

David Weldon


Moments are not designed to be directly serializable. They won't survive a round-trip to/from JSON. The best approach would be to serialize an ISO8601 formatted date, such as with moment().toISOString() or moment().format(). (toISOString is prefered, but will store at UTC instead of local+offset).

Then later, you can parse that string with moment(theString) and do what you want with it from there.

David's answer is also correct. Though it will rely on whatever Metor's default mechanism is for serializing Date objects, as Date also cannot exist directly in JSON. I don't know the specifics of Meteor - but chances are it's either storing an integer timestamp or just using Date.toString(). The ISO8601 format is much better suited for JSON than either of those.

UPDATE

I just took a glance at the docs for Meteor, which explain that they use an invented format called "EJSON". (You probably know this, but it's new to me.)

According to these docs, a Date is serialized as an integer timestamp:

{
  "d": {"$date": 1358205756553}
}

So - David's answer is spot on (and should remain the accepted answer). But also, if you are doing something other than just getting the current date/time, then you might want to use moment for that. You can use yourMoment.toDate() and pass that so Meteor will treat it with the $date type in it's EJSON format.

like image 22
Matt Johnson-Pint Avatar answered Sep 19 '22 05:09

Matt Johnson-Pint