В поле результатов 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.