В поле результатов Mongoose/MongoDB появляются undefined в Javascript
Есть ли что-то, что мне не хватает, что позволит элементу регистрироваться как объект с параметром, но когда я пытаюсь получить доступ к этому параметру, он undefined?
Что я пробовал до сих пор:
-
console.log(item)
= > { title: "foo", content: "bar" }
, это прекрасный
-
console.log(typeof item)
= > объект
-
console.log(item.title)
= > "undefined"
Я включу некоторые из контекста, если это будет иметь отношение к проблеме.
var TextController = function(myCollection) {
this.myCollection = myCollection
}
TextController.prototype.list = function(req, res, next) {
this.myCollection.find({}).exec(function(err, doc) {
var set = new Set([])
doc.forEach(function(item) {
console.log(item) // Here item shows the parameter
console.log(item.title) // "undefined"
set.add(item.title)
})
res.json(set.get());
})
}
На основании предложения я отбросил debugger
до этой строки, чтобы проверить, какой элемент на самом деле находится через отладчик ответов node. Вот что я нашел: http://hastebin.com/qatireweni.sm
Из этого я попробовал console.log(item._doc.title)
, и он отлично работает. Итак, это больше похоже на вопрос мангуста сейчас, чем что-либо.
Есть похожие вопросы, но они, похоже, связаны с 'this' доступом к объектам или они пытаются вывести объект за пределы функции. В этом случае я не думаю, что я делаю это, но сообщите мне, если я ошибаюсь. Благодаря
Ответы
Ответ 1
Попробуйте выполнить цикл for in
через item
и посмотреть, можете ли вы получить доступ к значениям.
for (var k in item) {
console.log(item[k]);
}
Если это сработает, это означало бы, что у ваших ключей есть символы non-printable
или что-то вроде этого.
Из того, что вы сказали в комментариях, похоже, что как-то item
является экземпляром примитивной оболочки String
.
например.
var s = new String('test');
typeof s; //object
s instanceof String; //true
Чтобы проверить эту теорию, попробуйте следующее:
eval('(' + item + ')').title;
Также может быть, что item
- это объект, который имеет метод toString
, который отображает то, что вы видите.
EDIT: Чтобы быстро выявить эти проблемы, вы можете использовать console.dir
вместо console.log
, так как он отображает интерактивный список свойств объекта. Вы также можете использовать точку останова и добавить часы.
Ответ 2
Решение
Вы можете вызвать метод toObject
для доступа к полям. Например:
var itemObject = item.toObject();
console.log(itemObject.title); // "foo"
Почему
Как вы отметили, что реальные поля хранятся в поле _doc
документа.
Но почему console.log(item)
= > { title: "foo", content: "bar" }
?
Из исходного кода mongoose (document.js), мы можем обнаружить, что метод toString
Document
вызывает toObject
. Таким образом, console.log
будет показывать поля "правильно". Исходный код показан ниже:
var inspect = require('util').inspect;
...
/**
* Helper for console.log
*
* @api public
*/
Document.prototype.inspect = function(options) {
var isPOJO = options &&
utils.getFunctionName(options.constructor) === 'Object';
var opts;
if (isPOJO) {
opts = options;
} else if (this.schema.options.toObject) {
opts = clone(this.schema.options.toObject);
} else {
opts = {};
}
opts.minimize = false;
opts.retainKeyOrder = true;
return this.toObject(opts);
};
/**
* Helper for console.log
*
* @api public
* @method toString
*/
Document.prototype.toString = function() {
return inspect(this.inspect());
};
Ответ 3
Убедитесь, что вы определили заголовок в своей схеме:
var MyCollectionSchema = new mongoose.Schema({
_id: String,
title: String
});
Ответ 4
У вас нет пробельных или смешных символов в ' title'
, не так ли? Их можно определить, если вы указали идентификаторы в определение объекта/карты. Например:
var problem = {
' title': 'Foo',
'content': 'Bar'
};
Это может привести к тому, что console.log(item)
будет отображаться так, как вы ожидаете, но вызовите проблему undefined
при доступе к свойству title
без предшествующего пробела.
Ответ 5
Я думаю, что использование метода "find" возвращает массив Documents.I пробовал это, и я смог распечатать заголовок
for (var i = 0; i < doc.length; i++) {
console.log("iteration " + i);
console.log('ID:' + docs[i]._id);
console.log(docs[i].title);
}
Ответ 6
Старый вопрос, но поскольку у меня тоже была проблема с этим, я отвечу на него.
Вероятно, это произошло потому, что вы используете find()
вместо findOne()
. Поэтому в конце вы вызываете метод для массива документов вместо документа, в результате чего обнаруживаете массив, а не один документ. Использование findOne()
позволит вам получить доступ к объекту в обычном режиме.
Ответ 7
Используйте findOne()
вместо find()
.
Метод find()
возвращает массив значений, даже если у вас есть только один возможный результат, вам нужно использовать элемент [0], чтобы получить его.
Метод findOne
возвращает один объект или none, тогда вы сможете получить доступ к его свойствам без проблем.
Ответ 8
Вы инициализируете свой объект?
function MyObject()
{
this.Title = "";
this.Content = "";
}
var myo1 = new MyObject();
Если вы не инициализируете или не устанавливаете заголовок. Вы получите undefined.