Y at-il quelque chose qui me manque qui permettrait à l'élément de se connecter en tant qu'objet avec un paramètre, mais lorsque j'essaie d'accéder à ce paramètre, il n'est pas défini?
Ce que j'ai essayé jusqu'à présent:
console.log(item)
=> { title: "foo", content: "bar" }
, c'est bonconsole.log(typeof item)
=> objetconsole.log(item.title)
=> "undefined"Je vais inclure une partie du contexte au cas où il serait pertinent au problème.
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());
})
}
Sur la base de la suggestion, j'ai laissé debugger
avant cette ligne pour vérifier quel élément est réellement via le débogueur de noeud. C'est ce que j'ai trouvé: http://hastebin.com/qatireweni.sm
A partir de cela, j'ai essayé console.log(item._doc.title)
et cela fonctionne très bien .. Donc, cela ressemble plus à une question de mangouste maintenant qu'à autre chose.
Il y a des questions similaires à celles-ci, mais elles semblent être liées à «cet» accès aux objets ou ils essaient de faire sortir l'objet de la portée de la fonction. Dans ce cas, je ne pense pas que je fais quoi que ce soit, mais informez-moi si je me trompe. Merci
Vous pouvez appeler la méthode toObject
pour accéder aux champs. Par exemple:
var itemObject = item.toObject();
console.log(itemObject.title); // "foo"
Comme vous le soulignez, les champs réels sont stockés dans le champ _doc
du document.
Mais pourquoi console.log(item)
=> { title: "foo", content: "bar" }
?
De le code source de mongoose (document.js) , nous pouvons constater que la méthode toString
de Document
appelle la méthode toObject
. Donc, console.log
affichera les champs 'correctement'. Le code source est indiqué ci-dessous:
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());
};
Assurez-vous que vous avez défini le titre dans votre schéma:
var MyCollectionSchema = new mongoose.Schema({
_id: String,
title: String
});
Essayez d’effectuer une boucle for in
sur item
et voyez si vous pouvez accéder aux valeurs.
for (var k in item) {
console.log(item[k]);
}
Si cela fonctionne, cela signifie que vos clés ont des caractères non-printable
ou quelque chose comme ça.
D'après ce que vous avez dit dans les commentaires, il semblerait que item
soit une instance d'un wrapper primitif String
.
Par exemple.
var s = new String('test');
typeof s; //object
s instanceof String; //true
Pour vérifier cette théorie, essayez ceci:
eval('(' + item + ')').title;
Il se peut également que item
soit un objet doté d'une méthode toString
qui affiche ce que vous voyez.
EDIT: Pour identifier rapidement ces problèmes, vous pouvez utiliser console.dir
au lieu de console.log
, car il affiche une liste interactive des propriétés de l’objet. Vous pouvez également mais un point d'arrêt et ajouter une montre.
Je pense que l’utilisation de la méthode 'find' renvoie un tableau de documents. J’ai essayé cela et j’ai pu imprimer le titre.
for (var i = 0; i < doc.length; i++) {
console.log("iteration " + i);
console.log('ID:' + docs[i]._id);
console.log(docs[i].title);
}
Vous n'avez pas d'espaces ni de caractères amusants dans ' title'
, n'est-ce pas? Ils peuvent être définis si vous avez cité des identificateurs dans la définition d'objet/de carte. Par exemple:
var problem = {
' title': 'Foo',
'content': 'Bar'
};
Cela pourrait entraîner l'affichage de console.log(item)
similaire à ce que vous attendez, mais le problème undefined
lorsque vous accédez à la propriété title
sans l'espace précédent.
Vieille question, mais comme j'ai eu un problème avec ça aussi, je vais y répondre.
Ceci est probablement dû au fait que vous utilisez find()
au lieu de findOne()
. En fin de compte, vous appelez une méthode pour un tableau de documents au lieu d'un document, ce qui aboutit à la recherche d'un tableau et non d'un document unique. Utiliser findOne()
vous permettra d’obtenir un accès normal à l’objet.
Si vous souhaitez uniquement obtenir les informations sans bénéficier de tous les avantages de la mangouste, sauvegardez, c.-à-d., Vous pouvez utiliser .lean () dans votre requête. Vos informations seront plus rapides et vous pourrez les utiliser directement en tant qu'objet.
https://mongoosejs.com/docs/api.html#query_Query-lean
Comme indiqué dans la documentation, il s'agit du meilleur choix pour les scénarios en lecture seule.
Utilisez findOne()
au lieu de find()
.
La méthode find()
renvoie un tableau de valeurs. Même si vous n'avez qu'un seul résultat possible, vous devrez utiliser l'élément [0] pour l'obtenir.
La méthode findOne
renvoie un objet ou aucun, vous pourrez alors accéder à ses propriétés sans aucun problème.
Êtes-vous en train d'initialiser votre objet?
function MyObject()
{
this.Title = "";
this.Content = "";
}
var myo1 = new MyObject();
Si vous n’initialisez pas ou n’avez pas défini de titre. Vous serez indéfini.
Une meilleure façon de traiter un problème de ce type consiste à utiliser doc.toObject()
comme ceci.
doc.toObject({ getters: true })
d'autres options incluent:
getters:
applique tous les getters (chemin et getters virtuels)virtuals:
appliquer des getters virtuels (peut remplacer l'option de getters)minimize:
supprime les objets vides (par défaut, true)transform:
une fonction de transformation à appliquer au document résultant avant de renvoyerdepopulate:
dépeupler les chemins remplis, en les remplaçant par leurs références d'origine (par défaut, false)versionKey:
s'il faut inclure la clé de version (true par défaut)ainsi, par exemple, vous pouvez dire
Model.findOne().exec((err, doc) => {
if (!err) {
doc.toObject({ getters: true })
console.log('doc _id:', doc._id) // or title
}
})
et maintenant ça va marcher