这很奇怪......我正在使用带有ref的populate()来填充我的架构中的数组,但是这些属性是不可访问的。换句话说,架构是这样的:
new Model('User',{
'name': String,
'installations': [ {type: String, ref: 'Installations'} ],
'count': Number,
}
当然,Insallations是另一种模式。
然后我发现&填充一组用户......
model.find({count: 0}).populate('installations').exec( function(e, d){
for(var k in d)
{
var user = d[k];
for(var i in user.installations)
{
console.log(user.installations[i]);
}
}
} );
到目前为止一切顺利!我看到打印好的数据,如下所示:
{ runs: 49,
hardware: 'macbookpro10,1/x86_64',
mode: 'debug',
version: '0.1' }
但是,如果我尝试实际访问任何这些属性,它们都是未定义的!例如,如果我添加另一个控制台日志:
console.log(user.installations[i].mode);
然后我看到为此日志打印了“undefined”。 如果我尝试操作对象,就像这样:
Object.keys(user.installations[i]).forEach(function(key) { } );
然后我得到一个典型的“[TypeError:Object.keys在非对象上调用]”错误,表明user.installations [i]不是一个对象(即使它被输出到控制台,就好像它一样) 。所以,我甚至尝试过像丑陋的东西......
var install = JSON.parse(JSON.stringify(user.installations[i]));
console.log(install, install.mode);
而且,第一个输出(install)是一个很好的对象,包含属性'mode'...但是第二个输出是未定义的。
是什么给出的?
答案 0 :(得分:3)
最后,我解决了这个......
我尝试做一个console.log(typeof user.installations [i]);并得到“字符串”作为输出。这似乎很奇怪,因为打印对象直接创建了控制台输出(上图),看起来像普通对象,而不是字符串。所以,我尝试做一个JSON.parse();在对象上,但收到错误“SyntaxError:Unexpected token r”
最后,我意识到发生了什么。我上面描述的“漂亮的控制台输出”是用\ n(换行符)格式化的字符串的结果。无论出于何种原因,我都没想到。 JSON.parse()错误是由于在尝试解析没有引号的对象键时node.js解析器已知的必要性;在这里看到SO问题: Why does JSON.parse('{"key" : "value"}') do just fine but JSON.parse('{key : "value"}') doesn't?。
具体来说,请注意我的情况下的JSON解析器在字符'r'上失败,这是“runs”的第一个字符,这是我的JSON字符串中的第一个键(上图)。起初我害怕我需要获得一个自定义的JSON解析器,但后来遇到了问题。
回顾我的原始架构。我使用String类型来定义安装引用,因为数组字段将安装的_id属性存储为String。我假设.populate()字段在输出时将对象转换为String。
最后,我仔细查看了Mongoose文档,并意识到我应该基于Schema.ObjectID引用对象。这解释了一切,但肯定让我在其他地方的模式和代码中做了一些修复......