1
votes

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?

1

1 Answers

2
votes

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();
})