Вставка объекта momentjs в коллекции Meteor
У меня есть простая коллекция Meteor, и я пытаюсь вставить документ, в который есть свойство momentjs. Поэтому я:
docId = Col.insert({m: moment()});
Однако, когда я пытаюсь вернуть этот документ с помощью
doc = Col.findOne({_id: docId})
Я получаю "Недопустимая дата" для doc.m следующим образом:
Object {_id: "wnHzTpHHxMSyMxmu3", m: "Invalid date"}
Кто-нибудь?!
Ответы
Ответ 1
Я настоятельно рекомендую хранить даты как объекты Date
и использовать момент для их форматирования после их получения. Например:
Posts.insert({message: 'hello', createdAt: new Date});
Затем позже, когда вы хотите отобразить дату:
var date = Posts.findOne().createdAt;
moment(date).format('MMMM DD, YYYY');
Ответ 2
Моменты не предназначены для прямой сериализации. Они не переживут кругосветное путешествие в/из JSON. Лучшим подходом было бы сериализовать дату форматирования ISO8601, например, с помощью moment().toISOString()
или moment().format()
. (toISOString
предпочтительнее, но будет хранить в UTC вместо локального + смещения).
Затем вы можете проанализировать эту строку с помощью moment(theString)
и делать то, что вы хотите от нее.
Ответ Дэвида также верен. Хотя он будет полагаться на любой механизм по умолчанию Metor для сериализации объектов Date
, поскольку Date
также не может существовать непосредственно в JSON. Я не знаю особенностей Метеор, но, скорее всего, он либо хранит целую временную метку, либо просто использует Date.toString()
. Формат ISO8601 намного лучше подходит для JSON, чем любой из них.
UPDATE
Я просто взглянул на документы для Метеор, которые объясняют, что они используют изобретенный формат под названием "EJSON". (Вы, наверное, знаете это, но это новое для меня.)
В соответствии с эти документы, Date
сериализуется как целая временная метка:
{
"d": {"$date": 1358205756553}
}
Итак - ответ Дэвида на месте (и должен оставаться принятым ответом). Но также, если вы делаете что-то другое, кроме как только получать текущую дату/время, тогда вы можете использовать для этого момент. Вы можете использовать yourMoment.toDate()
и передать это так, чтобы Meteor обрабатывал его с типом $date
в формате EJSON.
Ответ 3
Если вы хотите иметь объекты момента на find
и findOne
, сохраните его как дату, затем преобразуйте его при его обнаружении. Например:
Posts = new Mongo.Collection('posts', {
transform: function (doc) {
Object.keys(doc).forEach(field => {
if (doc[field] instanceof Date) {
doc[field] = moment(doc[field]);
}
});
return doc;
}
});
Posts.insert({
title: 'Hello',
createdAt: new Date()
});