节点JS中的JSON字符串化未序列化对象数组

节点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

我正在使用(NodeJS框架)

我试图对其中一个对象进行JSON.stringify,但当我这样做时,它会忽略其中一个字段(下面的rooms数组)

以下是console.log(对象)给我的信息:

[ { 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
    }
},