2

I'm using Node.js and Angular.js for a web project. I understand that date is saved as date if it's created on server using new Date() (e.g. 2015-04-08 04:15:18.712Z shown in Robomongo as Date type). However, if the date is created on client using new Date(), it is then saved as a string (e.g. 2015-04-07T04:58:12.771Z shown in Robomongo as String type), because it becomes a string through node API. How to make it save as a Date instead of String?

UPDATE: This is what I got based on Jason Cust's input. In node's server.js specify the reviver option as follows:

app.use(bodyParser.json({ reviver: function(key, value) {
    if ( typeof value === 'string' && value.length === 24) {
        if (value.match(/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ$/)){
            return new Date(value);
        }
    }
    return value;
}}));

This will automatically converts all date strings to date objects when data is sent from client to server.

If you want to do the same thing for the Angular.js client, I found a good blog by Andrew Davey Automatic JSON date parsing with AngularJS

newman
  • 6,841
  • 21
  • 79
  • 126
  • sounds like this would be an issue specific to the mongo client you're using. Which one are you using? – 0x6A75616E Apr 08 '15 at 04:35
  • I'm using `A node.js driver for MongoDB` v 1.4.31 from `Christian Amor Kvalheim` – newman Apr 08 '15 at 04:44
  • You can use also this function function isISO8601String(dateString) { var dateregex = /^([0-9]{4})\-([0-9]{1,2})\-([0-9]{1,2})([T\s]([0-9]{1,2}):([0-9]{1,2})(:([0-9]{1,2})(\.([0-9]+))?)?(Z|([+\-])([0-9]{1,2})(:([0-9]{1,2}))?)?)?$/; return dateregex.test(dateString); } – Farandole Sep 29 '15 at 14:36

1 Answers1

0

I am going to assume you are using JSON to send the date from your Angular app to your Node app. The JSON spec doesn't reconstitute a Date object so you will have to do it yourself first before inserting it into MongoDB.

Example:

// simulate JSON from HTTP request
var json = JSON.stringify({date: new Date()});
console.log(json);
// outputs: '{"date":"2015-04-08T04:50:04.252Z"}'
var obj = JSON.parse(json);
console.log(obj);
// outputs: { date: '2015-04-08T04:50:04.252Z' }
// reconstitute Date object
obj.date = new Date(obj.date);
console.log(obj);
// outputs: { date: Wed Apr 08 2015 00:50:04 GMT-0400 (EDT) }
Jason Cust
  • 10,743
  • 2
  • 33
  • 45
  • Yes, I'm using JSON to send data back and forth. I can't believe this is true. So, if I have a big and nested object to save, I have to find all the string dates and convert them real date before save it. Is there no workaround? – newman Apr 08 '15 at 05:03
  • Depending on what you are using to process HTTP request bodies you could specify a `reviver` for the [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) method to check if a string matches the format and convert it to a Date object. – Jason Cust Apr 08 '15 at 05:12
  • @miliu If your original question has been answered can you indicate it by accepting this answer? – Jason Cust Apr 08 '15 at 13:25
  • one more question before I accept your answer: Can you give me more info on how to hook up JSON.parse reviver in node.js? – newman Apr 08 '15 at 14:19
  • That requires a bit more info. Are you using [Express/Connect](http://expressjs.com/api.html#req.body) for handling requests? If so you would use the `reviver` option for [`bodyparser`](https://github.com/expressjs/body-parser#bodyparserjsonoptions). – Jason Cust Apr 08 '15 at 14:37
  • Oh, yes, in the meantime I figured out that bodyParser.json's options include reviver option which is passed to JSON.parser. This works well for passing date objects from client to node server. However, I wonder if there is similar mechanism for passing date objects from server to client? – newman Apr 08 '15 at 15:02
  • This would/could be the data pipeline: `db (string) --> server app (string or converted to Date) --> *JSON stringification to send to client* (string) --> client app (string or converted to Date)`. If you convert the string from the database to a Date on the server it will automatically be reconverted back to a string for the response to the client (you cannot send any objects in a response, just string representation of objects). So the client could use the same or similar reviver you use to reconstitute the strings to dates on the server when you stored them. – Jason Cust Apr 08 '15 at 15:10
  • So, how do I hook up this reviver function for the client on $http request? I just started playing with Node/MongoDB. At this point, I wonder if I should simply store all dates as string. – newman Apr 08 '15 at 15:16
  • You are venturing into a wholly different conversation although related. Again this all depends on what you are using on the client to process requests and responses. Most will allow the same type of configuration. – Jason Cust Apr 08 '15 at 15:21
  • Okay, I accepted your answer. Thank you very much for helping. – newman Apr 08 '15 at 15:29