Reputation: 973
I have already checked the other entries on StackOverflow
, but it did not help.
I am building a RESTapi
with node.js
, and I am using MongoDB
with mongoose
I have a Schema
that contains three different models. I am able to save POST
request to the entry. I am sure that entry is saved because I checked on atlas.mongo
. However, I have a problem when I am trying to use GET
request.
It gives this error:
Cast to ObjectId failed for value "" at path "_id" for model
These are my Models: (These models are in different files)
const Model1 = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
word1: { type: [String], require: true }
});
----------------------------------------------
const Model2 = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
word2: { type: [String], require: true }
});
----------------------------------------------
const Model3 = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
element1: { type: [String], default: ""},
element2: { type: [String], default: ""}
});
----------------------------------------------
const Word = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
md3: { type: mongoose.Schema.Types.Mixed, ref: 'Model3', require: true },
md2: { type: mongoose.Schema.Types.Mixed, ref: 'Model2', require: true },
md1: { type: mongoose.Schema.Types.Mixed, ref: 'Model1', require: true }
});
This is my POST request:
exports.entry_create = (req, res, next) => {
const newModel3 = new Model3({
_id: new mongoose.Types.ObjectId(),
element1: req.body.element1,
element2: req.body.element2
});
const newModel2 = new Model2({
_id: new mongoose.Types.ObjectId(),
word2: req.body.word2
});
const newModel1 = new Model1({
_id: new mongoose.Types.ObjectId(),
word1: req.body.word1
});
const newEntry = new Word({
_id: new mongoose.Types.ObjectId(),
md3: newModel3,
md2: newModel2,
md1: newModel1
});
newEntry
.save(); // i have also then() and catch() part
};
This is where I got the error on Postman
exports.entry_get_all = (req, res, next) => {
Word.find()
.select('_id md3 md2 md1')
.populate('md3')
.populate('md2')
.populate('md1')
.exec()
.then(docs => {
res.status(200).json({
numOfEntries: docs.length,
Entries: docs.map(doc => {
return {
_id: doc._id,
md3: doc.md3,
md2: doc.md2,
md1: doc.md1,
request: { type: 'GET' }
}
})
});
}); // i have also catch() part
};
What could be the problem? Is _id
's of md3, md2 & md1
returns null
?
Upvotes: 1
Views: 1600
Reputation: 729
I believe it has to do with your references md1, md2 and md3. The way you reference another model is by the _id, which in your case it's and ObjectId. That being said, when you define md1, md2, and md3 you say the type is mixed, not an ObjectId. Do this instead:
const Word = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
md3: { type: mongoose.Schema.Types.ObjectId, ref: 'Model3', require: true },
md2: { type: mongoose.Schema.Types.ObjectId, ref: 'Model2', require: true },
md1: { type: mongoose.Schema.Types.ObjectId, ref: 'Model1', require: true }
});
Also note: You don't need to explicitly create a new ObjectId when creating an instance of your model. If using mongoose, it creates the _id for you! So you can just create a new Word
like this:
let md1 = null;
let md2 = null;
let md3 = null;
const newModel3 = new Model3({
element1: req.body.element1,
element2: req.body.element2
});
// Save newModel3
newModel3.save()
.then((_md3) => {
md3 = _md3;
const newModel2 = new Model2({
word2: req.body.word2
});
return newModel2.save();
})
.then((_md2) => {
md2 = _md2;
const newModel1 = new Model1({
word1: req.body.word1
});
return newModel1.save();
})
.then((_md1) => {
md1 = _md1
const newEntry = new Word({
md3: md3._id,
md2: md2._id,
md1: md1._id
});
return newEntry.save();
})
Upvotes: 2