这个JavaScript对象如何转换为字符串?

时间:2018-04-03 06:11:42

标签: javascript arrays mongoose

我一直在为产品目录系统开发Node.JS / MongoDB后端,我遇到了一个奇怪的错误。

过程

首先,我从产品系列中加载产品信息。此产品包含诸如名称,描述以及文件上载ID列表之类的信息,这些ID指向字符串数组中产品的图像。 然后,我为每个上传ID加载每张照片的信息。然后我用一组文件信息对象替换上传ID字符串数组。 但是,当我输出结果产品对象时,图像列表是一个表示JavaScript的字符串列表,就好像它们是用代码编写的一样。

守则

// products.controller.js
async function populateImageInformation(productRecord) {
    let imageInfo = [];
    for(let uploadId of productRecord.images) {
        let imageData = await File.getByUploadId(uploadId);
        imageInfo.push(imageData);
        console.log(typeof imageData); // => object
    }
    console.log(typeof imageInfo); // => object
    console.log(typeof imageInfo[0]); // => object
    productRecord.images = imageInfo;
    console.log(typeof productRecord.images); // => object
    console.log(typeof productRecord.images[0]); // => string
    return productRecord;
}

async function getAll(req, res, next) {
    try {
        let productRecords = await Product.find({});
        for(let productRecordI in productRecords) {
            productRecords[productRecordI] = await populateImageInformation(productRecords[productRecordI]);
        }
        res.json(productRecords);
    } catch (e) {
        next(e);
    }
}

Mongoose模式文件:

// file.model.js
getByUploadId: function(uploadId) {
    return this.findOne({
        uploadId
    });
}

我不明白当我将productRecord.images属性设置为imageInfo时,数组中的值突然变为值的字符串表示形式。 weird string value

该字符串包含JSON,而是包含一个人类可读的字符串表示,表示如何将对象硬编码为JavaScript。这些字符串根本无法解析为JSON。 JSON期望密钥用双引号括起来,而生成的JavaScript代码却没有。

有没有理由这样做?我从未见过这种情况。

1 个答案:

答案 0 :(得分:1)

问题是由 mongoose架构引起的,它们保护模型是您在架构中声明的类型。通过find返回的对象是一个猫鼬模型,当您更新任何值时,它们会进行类型检查。

让我们来看看你的情景。我创造了一个例子。见下文

    const mongoose = require('mongoose');
    const db = require('./db');
    const Schema = mongoose.Schema;

    const productSchema = new Schema({
      name: {type: String},
      images: [String]  // Note schema have array of string
    });

    const productModel = mongoose.model('product', productSchema);

    db.connect().then(() => {
      //find record from productSchema
      return productModel.find({})
        .then((productRecords) => { //productRecords - don't forget is a mongoose model object

// productRecords from db  [{"name":"gilette","images":["idx","idy"],"_id":"5ac324c4fad317265b9df226","__v":0}]


          //TRIAL A
          for (let productRecordI in productRecords) {
            productRecords[productRecordI] = populateImageInformation(productRecords[productRecordI]);

          }
          console.log(typeof productRecords[0].images[0]); //=> string;


          //SOLUTION for the problem is copy mongoose data without reference
          //TRIAL B
          productRecords = JSON.parse(JSON.stringify(productRecords));
          for (let productRecordI in productRecords) {
            productRecords[productRecordI] = populateImageInformation(productRecords[productRecordI]);

          }
          console.log(typeof productRecords[0].images[0]); //=> Object;

        });

      //just a mock function change images to object
      function populateImageInformation(productRecord) {
        imageInfo = [];
        for (let uploadId of productRecord.images) {
          let imageData = {name: uploadId};
          imageInfo.push(imageData);
          console.log(typeof imageData); // => object
        }
        productRecord.images = imageInfo;
        return productRecord;
      }


    }).catch((err) => {
      console.log('err', err);
    });