节点JS中的JSON字符串化未序列化对象数组
我正在使用(NodeJS框架) 我试图对其中一个对象进行JSON.stringify,但当我这样做时,它会忽略其中一个字段(下面的rooms数组) 以下是console.log(对象)给我的信息:节点JS中的JSON字符串化未序列化对象数组,json,node.js,express,sails.js,waterline,Json,Node.js,Express,Sails.js,Waterline,我正在使用(NodeJS框架) 我试图对其中一个对象进行JSON.stringify,但当我这样做时,它会忽略其中一个字段(下面的rooms数组) 以下是console.log(对象)给我的信息: [ { rooms: [ [Object], [Object] ], state: '53df76c278999310248072c6', name: 'Sydney Center', menuItems: null, createdAt: Mon Aug 04 201
[ { rooms: [ [Object], [Object] ],
state: '53df76c278999310248072c6',
name: 'Sydney Center',
menuItems: null,
createdAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
updatedAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
id: '53dff0205c89c03428a31cee' },
{ rooms: [ [Object], [Object], [Object] ],
state: '53df76c278999310248072c6',
createdAt: Mon Aug 04 2014 23:43:21 GMT+0300 (Jerusalem Summer Time),
menuItems: null,
name: 'Batata Center',
updatedAt: Mon Aug 04 2014 23:51:11 GMT+0300 (Jerusalem Summer Time),
id: '53dff06a5c89c03428a31cf3' } ]
JSON输出(未打印文件室):
有什么问题吗?
房间数据似乎很好
对于完整功能(SailsJS):
已编辑
模式:
schema: true,
attributes: {
name: {
type: 'string',
required: true,
minLength: 5
},
// Many-To-Many association with Teacher model
teachers: {
collection: 'teacher',
via: 'centers'
},
// One-To-Many association with State model
state: {
model: 'state'
},
// One-To-Many association with Room model
rooms: {
collection: 'room',
via: 'center'
},
// One-To-One association with Principal model
principal: {
model: 'principal'
},
menuItems: {
type: 'array',
defaultsTo: null
}
},
因为Waterline查询返回的是模型,而不是普通的javascript对象,所以它们具有附加的属性和函数。其中一个是重写的
toJSON()
函数,该函数删除尚未填充的属性。这里似乎发生的事情是,您将对象附加到父模型,而父模型不知道它有已填充的子模型,因此它会删除这些值
这背后的原因是,如果查询所有用户,并且不填充房间,则不会得到显示空房间数组的错误结果
我不确定您在这里操作的是什么,但是如果您
.cloneDeep
,它之所以有效,是因为它删除了自定义toJSON
字段。当您从这样的查询中变异父对象时,这是推荐的策略。我的第一个猜测是,您的mongoose模式为toJSON
定义了忽略rooms属性的转换。您能发布您为所讨论的模型定义的模式吗?可能是异步计时的事情。将console.log添加到代码中(在最后一个return语句之前)以排除这种情况。@PeterLyons我添加了模式。@RobertLevy,我看到了,看到了我打印的日志,在哪里,没有帮助。好的,我可以肯定地说这与深度克隆有关,我在映射内将赋值更改为u.cloneDeep(),现在它给出了合理的结果。我仍然没有很好的解释:)我同意@particlebanana!看起来,尽管在开始时调用了“populate”,但最终地图中的“rooms”未填充的原因与线程有关.cloneDeep()
解决了这个问题。
getCentersData: function(req, res) {
sails.log.info('Teacher.getCentersData: ', req.user.id);
var userId = req.user.id;
async.auto({
teacher: function(cb) {
Teacher.findOne({ user: userId }).populate('centers').exec(cb);
},
centers: [
'teacher', function(cb, results) {
var allCentersIds = _.pluck(results.teacher.centers, 'id');
Center.findById(allCentersIds).populate('rooms').exec(cb);
}
],
rooms: [
'centers', function(cb, results) {
var allRoomIds = [];
_.each(results.centers, function(center) {
allRoomIds = _.union(allRoomIds, _.pluck(center.rooms, 'id'));
});
Room.findById(allRoomIds).populate('children').exec(cb);
}
],
children: [
'rooms', function(cb, results) {
var allChildrenIds = [];
_.each(results.rooms, function (room) {
allChildrenIds = _.union(allChildrenIds, _.pluck(room.children, 'id'));
});
Child.findById(allChildrenIds).populate('parents').exec(cb);
}
],
parentUsers: ['children', function(cb, results) {
var allParentIds = [];
_.each(results.children, function (child) {
allParentIds = _.union(allParentIds, _.pluck(child.parents, 'id'));
});
Parent.findById(allParentIds).populate('user').exec(cb);
}],
map: ['parentUsers', function (cb, results) {
// map children to parents
var parentsMapper = _.indexBy(results.parentUsers, 'id');
var childrenMappedToParents = _.map(results.children, function (child) {
var _child = child.toObject();
_child.parents = _.map(child.parents, function (parent) {
return parentsMapper[parent.id];
});
return _child;
});
var childrenMapper = _.indexBy(childrenMappedToParents, 'id');
// map rooms to children
var roomsMappedToChildren = _.map(results.rooms, function (room) {
var _room = room.toObject();
_room.children = _.map(room.children, function (child) {
return childrenMapper[child.id];
});
return _room;
});
var roomsMapper = _.indexBy(roomsMappedToChildren, 'id');
// map center to rooms
var centersMappedToRooms = _.map(results.centers, function (center) {
var _center = center.toObject();
_center.rooms = _.map(center.rooms, function (room) {
return roomsMapper[room.id];
});
return _center;
});
sails.log.info('centersMappedToRooms',centersMappedToRooms ); // includes rooms array
sails.log.info('centersMappedToRooms json: ', JSON.stringify(centersMappedToRooms)); // does not include rooms array
return cb(null, centersMappedToRooms);
}]
}, function(err, results) {
if (err) {
return res.serverError(err);
}
// added prints
sails.log.info("results.map: ", results.map);
sails.log.info("JSON.stringify(results.map): ", JSON.stringify(results.map)); // same same, does not print the rooms array
return res.json(results.map);
});
},
schema: true,
attributes: {
name: {
type: 'string',
required: true,
minLength: 5
},
// Many-To-Many association with Teacher model
teachers: {
collection: 'teacher',
via: 'centers'
},
// One-To-Many association with State model
state: {
model: 'state'
},
// One-To-Many association with Room model
rooms: {
collection: 'room',
via: 'center'
},
// One-To-One association with Principal model
principal: {
model: 'principal'
},
menuItems: {
type: 'array',
defaultsTo: null
}
},