我一直在为产品目录系统开发 Node.JS/MongoDB 后端,但遇到了一个奇怪的错误。
流程
首先,我从产品集合中加载产品信息。该产品包含名称、描述等信息,以及指向字符串数组中的产品图像的文件上传 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
时,数组中的值突然变成了值的字符串表示形式。
该字符串不包含 JSON,而是包含人类可读的字符串表示形式,表示对象如何硬编码到 JavaScript 中。这些字符串根本无法解析为 JSON。 JSON 期望键用双引号括起来,而生成的 JavaScript 代码没有这个。
发生这种情况有什么原因吗?我从未见过这种情况发生。
最佳答案
问题是由于 mongoose schema 造成的,它们通过您在 schema 中声明的类型来保护模型。 find 返回的对象是一个 Mongoose 模型,当您更新其上的任何值时,它们会进行类型检查。
让我们来看看您的场景。我创建了一个例子。见下文
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);
});
关于javascript - 这个 JavaScript 对象是如何转换为字符串的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49623356/