Поля результатов Mongoose/MongoDB в Javascript не определены
есть ли что-то, что мне не хватает, что позволило бы элементу регистрироваться как объект с параметром, но когда я пытаюсь получить доступ к этому параметру, он не определен?
что я пробовал до сих пор:
-
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
до этой линии, чтобы проверить, что элемент на самом деле через узел отладчика.расх. Вот что я нашел : http://hastebin.com/qatireweni.sm
из этого я пробовал console.log(item._doc.title)
и он работает просто отлично.. Теперь это больше похоже на вопрос мангуста, чем на что-либо другое.
есть вопросы, подобные этому, но они, похоже, связаны с "этим" доступом к объектам или они пытаются получить объект за пределами области действия функции. В этом случае я не думаю, что делаю что-то из этого, но сообщите мне, если я ошибаюсь. Спасибо
9 ответов
решение
можно назвать toObject
метод для доступа к полям. Например:
var itemObject = item.toObject();
console.log(itemObject.title); // "foo"
почему
как вы указали, что реальные поля хранятся в _doc
поле документа.
а зачем console.log(item)
=>{ title: "foo", content: "bar" }
?
С исходный код мангуста(документ.в 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());
};
убедитесь, что вы определили название в схеме:
var MyCollectionSchema = new mongoose.Schema({
_id: String,
title: String
});
попробуйте 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
, так как он отображает интерактивный список свойств объекта. Вы также можете только точку останова и добавить часы.
у вас нет пробелов или забавных персонажей в ' title'
, да? Они могут быть определены, если вы ввели идентификаторы в определение объекта/карты. Например:
var problem = {
' title': 'Foo',
'content': 'Bar'
};
что может вызвать console.log(item)
для отображения аналогично тому, что вы ожидаете, но вызвать ваш undefined
проблема при доступе к title
свойство без предшествующего пространства.
Я думаю, что использование метода 'find' возвращает массив документов.Я попробовал это, и я смог напечатать заголовок
for (var i = 0; i < doc.length; i++) {
console.log("iteration " + i);
console.log('ID:' + docs[i]._id);
console.log(docs[i].title);
}
старый вопрос, но так как у меня тоже была проблема с этим, я отвечу на него.
Вероятно, это произошло потому, что вы используете find()
вместо findOne()
. Таким образом, в конце концов вы вызываете метод для массива документов вместо документа, в результате чего находите массив, а не один документ. Используя findOne()
позволит вам получить доступ к объекту нормально.
использовать findOne()
вместо find()
.
на find()
метод возвращает массив значений, даже если у вас есть только один возможный результат, вам нужно будет использовать item[0], чтобы получить его.
на findOne
метод возвращает один объект или нет, тогда вы сможете получить доступ к его свойствам без проблем.
вы инициализируете свой объект?
function MyObject()
{
this.Title = "";
this.Content = "";
}
var myo1 = new MyObject();
Если вы не инициализируете или не установили заголовок. Вы получите неопределенность.
лучший способ решить такую проблему-использовать doc.toObject()
такой
doc.toObject({ getters: true })
другие функции включают в себя:
-
getters:
применить все геттеры (путь и виртуальные геттеры) -
virtuals:
применить виртуальные геттеры (газопоглотители можете переопределить параметр) -
minimize:
удалить пустые объекты (по умолчанию true) -
transform:
функция преобразования для применения к результирующему документу перед возвратом -
depopulate:
удалите все заполненные пути, заменив их исходными ссылками (по умолчанию false) -
versionKey:
включать ли ключ версии (по умолчанию true)
так, например, вы можете сказать
Model.findOne().exec((err, doc) => {
if (!err) {
doc.toObject({ getters: true })
console.log('doc _id:', doc._id) // or title
}
})
и теперь он будет работать