JSON在Node JS中进行字符串化,而不是序列化对象数组

时间:2014-08-05 15:31:40

标签: json node.js express sails.js waterline

我正在使用sails.js(节点js框架)。

我正在尝试JSON.stringify其中一个对象,但是当我这样做时,它会省略其中一个字段(下面的房间数组)。

这是console.log(object)给我的:

[ { 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输出(不打印房间):

    [
      {
        "state": "53df76c278999310248072c6",
        "name": "Sydney Center",
        "menuItems": null,
        "createdAt": "2014-08-04T20:42:08.885Z",
        "updatedAt": "2014-08-04T20:42:08.885Z",
        "id": "53dff0205c89c03428a31cee"
      },
      {
        "state": "53df76c278999310248072c6",
        "createdAt": "2014-08-04T20:43:21.999Z",
        "menuItems": null,
        "name": "Batata Center",
        "updatedAt": "2014-08-04T20:51:11.740Z",
        "id": "53dff06a5c89c03428a31cf3"
      }
    ]

可能是什么问题? 房间数据似乎很好。

对于完整的功能(SailsJS):

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);
    });

},

EDITED

架构:

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

1 个答案:

答案 0 :(得分:8)

由于Waterline查询返回的是模型,而不是普通的javascript对象,因此它们具有其他属性和功能。其中一个是重写的toJSON()函数,它删除了尚未填充的属性。这里似乎发生的是你将对象附加到父模型,该模型不知道它已经填充了子项,因此它剥离了值。

这背后的原因是,如果您查询所有用户而不填充房间,则不会得到显示空房间数组的错误结果。

我不确定你在这里操作的是什么,但如果_.cloneDeep是因为它删除了自定义toJSON字段,它的工作原理。当您从这样的查询中改变父对象时,这是推荐的策略。