Search code examples
typescriptmongoosemongoose-schemamongoose-populate

TypeScript with Mongoose: cannot read property 'CasterConstructor' of undefined


I am writing a node.js application using TypeScript and Mongoose. I am using the TypeScript model approach and continue to receive "cannot read property CasterConstructor' of undefined" when I call the create method to create a new subdocument. An example of the code is outlined below:

seat.ts:
export let SeatSchema: Schema = new Schema({
    travelerId: {type: Schema.Types.ObjectId, required: true},
    seatClass: {type: Schema.Types.String, minlength: 5, maxlength:10, required: true, enum: [“FirstClass”, “Coach”]},
    row: {type: Schema.Types.Number, required: true},
    section: {type: Schema.Types.Number, required: true},
    hasBoarded: {type: Schema.Types.Boolean, required: false}
});


plane.ts:
export let PlaneSchema: Schema = new Schema({
    manufacturer: {type: Schema.Types.String, required: true},
    seatsChart: [SeatSchema],
    routeId: [{type: Schema.Types.ObjectId, ref: ‘routes’, required: true}];

iseat.ts: 
export interface ISeat {
    travelerId: string,
    seatClass: string,
    row: number,
    section: number,
    hasBoarded: boolean
}


iplane.ts:
export interface IPlane {
    manufacturer: string,
    seatsChart: Types.DocumentArray<ISeatModel>,
    routeId: [string]
}

iseatmodel.ts:
export interface ISeatModel extends ISeat, Subdocument {
}

iplanemodel.ts:
export interface IPlaneModel extends IPlane, Document {
}

planerepository.ts:
constructor(db) {
    this._model: Model<IPlaneModel> = db.model<IPlaneModel>(“Plane”, PlaneSchema);
}
.
.
.
addNewSeat(planeId: string, seat: ISeat) {
    let plane: IPlaneModel = await this._model.findById(planeId);
    let newSeat: ISeatModel = plane.SeatsChart.create(seatAttributes);
    plane.seatsChart.push(newSeat);
    let planeUpdated: IPlane = await plane.save();
}

This is the error I keep receiving:

TypeError: Cannot read property 'casterConstructor' of undefined
    at Array.create (/node_modules/mongoose/lib/types/documentarray.js:236:35)
        .
        .
        .
        .
        .

What could I be missing, and is this the right approach altogether?

Update

After I switched to using push, the problem seems to be in /mongoose/lib/types/array.js, _checkManualPopulation:

function _checkManualPopulation(arr, docs) {
  var ref = arr._schema.caster.options && arr._schema.caster.options.ref;
  if (arr.length === 0 &&
      docs.length > 0) {
    if (_isAllSubdocs(docs, ref)) {
      arr._parent.populated(arr._path, [], { model: docs[0].constructor });
    }
  }
}

For some reason, the _schema object is undefined when push gets called which results in the exception. I am not sure if this is a bug or if something else is not getting called that would otherwise initialize the _schema property?


Solution

  • I found the answer. I ended up having to move logic that creates the database connection from a separate library to an inversify.config.js file in the main project and inject the mongoose connection into each repository. That seems to have fixed the problem.