Mongoose: CastError: Echec de la conversion en ObjectId pour la valeur “” sur le chemin “_id”

Je suis nouveau sur node.js, j’ai donc le sentiment que c’est une bêtise que j’ai négligée, mais je n’ai pas été en mesure de trouver une réponse qui résout mon problème. Ce que j’essaie de faire est de créer un chemin qui créera un nouvel object enfant, l’appenda au tableau d’enfants du parent, puis renverra l’object enfant au demandeur. Le problème que je rencontre est que si je passe l’id de la chaîne à findById, le noeud se bloque avec

TypeError: L’object {} n’a pas de méthode ‘cast’

Si j’essaie plutôt de passer un ObjectId, j’obtiens

CastError: Echec de la conversion vers ObjectId pour la valeur “[object Object]” sur le chemin “_id”

Voici un aperçu de mon code:

var mongoose = require('mongoose'); var Schema = mongoose.Schema; var ObjectId = Schema.ObjectId; //Have also sortinged Schema.Types.ObjectId, mongoose.ObjectId mongoose.connect('mongodb://user:password@server:port/database'); app.get('/myClass/:Id/childClass/create', function(request, result) { var id = new ObjectId(request.params.Id); MyClass.findById(id).exec( function(err, myClass) { if (err || !myClass) { result.send("error: " + err + "
" + JSON.ssortingngify(id) || ("object '" + request.params.Id + "' not found: " + id)); return; } var child = ChildClass(); myClass.Children.addToSet(child); myClass.save(); result.send(child); }); });

Si j’exécute ce code avec le chemin “/ myClass / 51c35e5ced18cb901d000001 / childClass / create”, il s’agit de la sortie du code:

error: CastError: Echec de la conversion vers ObjectId pour la valeur “[object Object]” sur le chemin “_id” {“chemin”: “51c35e5ced18cb901d000001”, “instance”: “ObjectID”, “validators”: [], “setters”: [ ], “getters”: [], “_ index”: null}

J’ai essayé d’utiliser findOne et de passer {_id: id} à la place, mais cela semble être exactement ce que fait FindById. J’ai essayé les différentes classes pour ObjectId que j’ai vues énumérées sur d’autres sites. J’ai essayé d’appeler ObjectId () comme une fonction au lieu d’un constructeur et cela retourne undefined. À ce stade, je suis à court d’idées et il ne semble pas que rechercher une réponse sur Google puisse aider. Des idées sur ce que je fais mal?

En outre, comme je l’ai dit, je connais pour la première fois noeud / Mongo / Mongoose / Express. Par conséquent, s’il existe un meilleur moyen d’atteindre mon objective, merci de me le faire savoir. J’apprécie tous les commentaires.

MODIFIER:

Après la solution de rechange de Peter Lyons, j’ai cherché dans une autre erreur que j’étais en train de chercher et ai trouvé findByIdAndUpdate, qui fonctionne comme prévu et fait exactement ce que j’espérais faire. Je ne suis toujours pas sûr de savoir pourquoi findById et findOne me causaient de tels problèmes et je suis curieux de savoir (peut-être qu’un rapport de bogue doit être rédigé), je vais donc laisser cette case ouverte au cas où quelqu’un d’autre aurait une réponse.

Réponse courte: utilisez mongoose.Types.ObjectId .

Mongoose (mais pas mongo) peut accepter les identifiants d’object en tant que chaînes et les “caster” correctement pour vous, utilisez donc simplement:

 MyClass.findById(req.params.id) 

Cependant, si req.params.id n’est pas un format valide pour une chaîne d’identification mongo, une exception que vous devez capturer sera req.params.id .

La principale source de confusion à comprendre est que mongoose.SchemaTypes contient des éléments que vous utilisez uniquement lors de la définition de schémas mongoose et mongoose.Types contient des éléments que vous utilisez lors de la création des objects de données que vous souhaitez stocker dans la firebase database ou des objects de requête. Donc mongoose.Types.ObjectId("51bb793aca2ab77a3200000d") , vous donnera un object que vous pouvez stocker dans la firebase database ou utiliser dans des requêtes, et lèvera une exception si une chaîne d’ID non valide lui est atsortingbuée.

findOne prend un object de requête et transmet une instance de modèle unique au rappel. Et findById est littéralement un wrapper de findOne({_id: id}) ( voir le code source ici ). Just find prend un object de requête et transmet un rappel à un tableau d’instances de modèle correspondantes.

Allez-y doucement. C’est déroutant, mais je peux vous garantir que vous êtes en train de devenir confus et que vous ne rencontrez pas d’insectes chez la mongoose pour le moment. C’est une bibliothèque assez mature, mais il faut un certain temps pour bien la comprendre.

L’autre chose suspecte que je vois dans votre extrait de ChildClass n’utilise pas new lors de l’instanciation de ChildClass . Au-delà de cela, vous devez publier votre code de schéma pour que nous puissions vous aider à localiser les éventuels erreurs restantes de CastErrors.

J’ai rencontré cette erreur, car la valeur que vous souhaitez filtrer dans le champ _id n’est pas au format ID, un “if” devrait résoudre ce problème.

 const mongoose = require('mongoose'); console.log(mongoose.Types.ObjectId.isValid('53cb6b9b4f4ddef1ad47f943')); // true console.log(mongoose.Types.ObjectId.isValid('whatever')); // false 

Pour résoudre, toujours valider si la valeur du critère de recherche est un ObjectId valide

 if(params.q) { criteria.$or = [] if(mongoose.Types.ObjectId.isValid(params.id)) { criteria.$or.push({ _id: params.q }) } criteria.$or.push({ name: { $regex: params.q, $options: 'i' }}) criteria.$or.push({ email: { $regex: params.q, $options: 'i' }}) criteria.$or.push({ password: { $regex: params.q, $options: 'i' }}) } return UserModule.find(criteria).exec(() => { // do stuff }) 

Pour tous ceux qui sont restés coincés dans ce problème, mais ne pouvaient toujours pas le résoudre: je suis tombé sur la même erreur et j’ai trouvé le champ _id vide.

Je l’ai décrit ici plus en détail. Je n’ai toujours pas trouvé de solution, sauf de changer les champs de _id en champs non-ID, ce qui est un sale bidouillage pour moi. Je vais probablement déposer un rapport de bogue pour la mongoose. Toute aide serait appréciée!

Edit: j’ai mis à jour mon fil. J’ai classé un billet et ils ont confirmé le problème manquant. Cela va être corrigé dans la version 4.xx qui a une version candidate disponible actuellement. Le RC n’est pas recommandé pour une utilisation productive!

Si vous rencontrez ce problème et que vous effectuez une opération de remplissage quelque part, consultez ce problème relatif à Mongoose .

Mettez à jour Mongoose 4.0 et le problème a été corrigé.

Ayant le même problème, j’ai juste forcé l’identifiant dans une chaîne.

Mon schéma:

 const product = new mongooseClient.Schema({ retailerID: { type: mongoose.SchemaTypes.ObjectId, required: true, index: true } }); 

Et puis, lors de l’insertion:

 retailerID: `${retailer._id}` 

Je recevais cette erreur CastError: la conversion vers ObjectId a échoué pour la valeur “[object Object]” sur le chemin “_id” après avoir créé un schéma, puis l’a modifié et n’a pas pu le localiser. J’ai supprimé tous les documents de la collection et je pouvais append un object mais pas un second. J’ai fini par supprimer la collection à Mongo et cela a fonctionné lorsque Mongoose a recréé la collection.

Pour mémoire: j’ai eu cette erreur en essayant de remplir un sous-document de manière incorrecte:

 { [CastError: Cast to ObjectId failed for value "[object Object]" at path "_id"] message: 'Cast to ObjectId failed for value "[object Object]" at path "_id"', name: 'CastError', type: 'ObjectId', path: '_id' value: [ { timestamp: '2014-07-03T00:23:45-04:00', date_start: '2014-07-03T00:23:45-04:00', date_end: '2014-07-03T00:23:45-04:00', operation: 'Deactivation' } ], } 

look ^ value est un tableau contenant un object: faux!

Explication: J’envoyais des données de php à une API node.js de la manière suivante:

 $history = json_encode( array( array( 'timestamp' => date('c', time()), 'date_start' => date('c', time()), 'date_end' => date('c', time()), 'operation' => 'Deactivation' ))); 

Comme vous pouvez le voir, $ history est un tableau contenant un tableau. C’est pourquoi Mongoose essaie de remplir _id (ou tout autre champ) avec un tableau plutôt qu’avec un Scheme.ObjectId (ou tout autre type de données). Les oeuvres suivantes:

 $history = json_encode( array( 'timestamp' => date('c', time()), 'date_start' => date('c', time()), 'date_end' => date('c', time()), 'operation' => 'Deactivation' )); 

J’avais le même problème. Il s’avère que mon Node.js était obsolète. Après la mise à niveau, cela fonctionne.

J’ai également rencontré cette erreur mangeuse CastError: l’échec de la conversion en ObjectId pour la valeur \ “583fe2c488cf652d4c6b45d1 \” dans le chemin \ “_ id \” du modèle User

Donc, je lance la commande npm list pour vérifier la version de mongodb et mongoose dans mon local. Voici le rapport: ……
……
├── mongodb@2.2.19
Ong mongoose@4.7.2
…..

Il semble qu’il y ait un problème avec cette version de Mongodb, alors ce que j’ai fait est de désinstaller et d’essayer d’utiliser une version différente telle que 2.2.16

$ npm uninstall mongodb , il supprimera mongodb de votre répertoire node_modules. Après cela, installez la version inférieure de mongodb.
$ npm install mongodb@2.2.16
Enfin, je redémarre l’application et le CastError est parti !!