这个JavaScript对象是如何转换成字符串的?
我一直在为产品目录系统开发Node.JS/MongoDB后端,我遇到了一个奇怪的bug 过程 首先,我从产品集合中加载产品信息。此产品包含名称、说明等信息,还包含指向字符串数组中产品图像的文件上载ID列表。 然后,对于每个上传ID,加载每个照片的信息。然后,我将upload ID字符串数组替换为文件信息对象数组。 但是,当我输出结果产品对象时,图像列表是一个字符串列表,表示JavaScript,就好像它们是用代码编写的一样 代码 Mongoose架构文件:这个JavaScript对象是如何转换成字符串的?,javascript,arrays,mongoose,Javascript,Arrays,Mongoose,我一直在为产品目录系统开发Node.JS/MongoDB后端,我遇到了一个奇怪的bug 过程 首先,我从产品集合中加载产品信息。此产品包含名称、说明等信息,还包含指向字符串数组中产品图像的文件上载ID列表。 然后,对于每个上传ID,加载每个照片的信息。然后,我将upload ID字符串数组替换为文件信息对象数组。 但是,当我输出结果产品对象时,图像列表是一个字符串列表,表示JavaScript,就好像它们是用代码编写的一样 代码 Mongoose架构文件: // file.model.js ge
// file.model.js
getByUploadId: function(uploadId) {
return this.findOne({
uploadId
});
}
我不明白,当我将productRecord.images
属性设置为imageInfo
时,数组中的值突然变成了值的字符串表示形式。
该字符串不包含JSON,而是包含一个可读的字符串表示,表示对象如何硬编码为JavaScript。这些字符串根本无法解析为JSON。JSON希望将键包装在双引号中,而生成的JavaScript代码没有这样的内容
发生这种情况有什么原因吗?我从未见过这种情况。问题是由于猫鼬模式造成的,它们通过模式中声明的类型保护模型。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);
});
可能是这样,但..productRecord.images是字符串数组。。。因此,可能是将对象转换为字符串以匹配typesJavaScript不关心类型,我甚至在设置数组之前尝试删除它,但它没有改变任何东西可能res.json有副作用?它做什么?
res.json
在这里没有效果。数据在发送回浏览器之前被篡改。问题中缺少产品的架构。
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);
});