1

I have a collection of activities and MongoDB. Activities also have a date. I'm trying to dynamically build a table with all activities saved in my collection. Therefor I want to change the format of the date with moment.js right before I send the array of JSON objects to my jade file.

I tried to make a new results array and send this one over to my jade file.

    router.get('/', function(req, res, next) {
      activitiesController.getActivities(function(results) {
        if(!results) {
          results = [];
        }
        for(var key in results) {
          results[key].date = moment(results[key].date).format('ddd, hA');
        }
        res.render('index', {
          activities: results
        })
      });
    });

This is how the results array looks:

[{
    "_id" : ObjectId("56fe2c0d7afcafa412ae19c2"),
    "title" : "Fitnessstudios",
    "category" : "Sport",
    "time" : 2,
    "date" : ISODate("2016-03-30T00:00:00.000Z"),
    "__v" : 0
}]

2 Answers2

1

Your problem is that the value you are passing to moment.js is:

ISODate("2016-03-30T00:00:00.000Z")

when it wants just the date string part:

"2016-03-30T00:00:00.000Z"

So get just the date string and pass that, the snippet below shows how to do that.

var dateString = 'ISODate("2016-03-30T00:00:00.000Z")'.replace(/^[^\"]+\"([^\"]+)\".*$/,'$1');

document.write(dateString);

moment.js will likely parse an ISO string just fine without further help, however I think it's much better to tell it the format, so you should use something like:

var dateString = results[key].date.replace(/^[^\"]+\"([^\"]+)\".*$/,'$1');
results[key].date = moment(dateString,'YYYY-MM-DDThh:mm:ss.sssZ').format('ddd, hA');

// Wed, 10AM

And you should not use for..in over an array, you may find properties other than those you expect and in a different order. Use a plain for, while or do loop or one of the looping methods like forEach, map, etc. as appropriate.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • Thinking about it further, the regular expression can be simplified to `/\"([^\"]+)\"/`, there's no need to match the rest of the string. – RobG Apr 01 '16 at 13:05
  • Doesn't work. Could the problem be, that I defined an activitySchema with date: Date and the date formats I try to pass in my for-loop do not fit this schema anymore? – Thomas Göhringer Apr 01 '16 at 13:08
  • 1
    I don't know. What is the actual value and Type of `results[key].date` (e.g. Date, String, …)? I assumed it was the string 'ISODate("2016-03-30T00:00:00.000Z")' but maybe that's just what you're getting in the console? – RobG Apr 01 '16 at 13:20
  • value is Wed Mar 30 2016 02:00:00 GMT+0200 (Mitteleuropäische Sommerzeit) and when I log `typeof results[key].date` to my console it only says object. – Thomas Göhringer Apr 02 '16 at 08:30
0

Change this:

moment(results[key].date).format('ddd, hA');

to

moment(new Date(results[key].date.toString()),moment.ISO_8601).format('ddd, hA');
AJS
  • 1,993
  • 16
  • 26
  • and you can loop as he has done everything else should work fine – AJS Apr 01 '16 at 11:47
  • I didn't know you can loop arrays with `for..in` :), [I still won't use it anyway](http://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-such-a-bad-idea). – A1rPun Apr 01 '16 at 11:55
  • It is deprecated to put a string into moment(). https://github.com/moment/moment/issues/1407 – Thomas Göhringer Apr 01 '16 at 12:12
  • i have edited the answer see if that works should lose the warning – AJS Apr 01 '16 at 12:30
  • I tried `results[key].date = moment(results[key].date.toString(),'YYYY-MM-DDThh:mm:ss.sssZ').format('ddd, hA');` but it didn't work. The problem is, that I cannot overwrite the old date field in the JSON. – Thomas Göhringer Apr 01 '16 at 12:42
  • 2
    No, **do not** do that. moment.js has a perfectly good parser that is much superior to that common in browsers, use that and tell it the format. It makes no sense to use the Date constructor to parse the string, then generate another non–standard, implementation dependent string, then parse that with moment.js without an any time telling the parser what it's getting. – RobG Apr 01 '16 at 12:44
  • @ThomasG, i have edited my answer see if that works for you – AJS Apr 04 '16 at 06:11