网站搜索

TypeScript 与 Mongoose:无法读取未定义的属性 'CasterConstructor'


我正在使用 TypeScript 和 Mongoose 编写一个 node.js 应用程序。我使用的是 TypeScript 模型方法,但在调用 create 方法创建新的子文档时,仍然收到“cannot read property 'CasterConstructor' of undefined”的错误。下面列出了一个代码示例:

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

这是我一直收到的错误信息:

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

我可能漏掉了什么,这种方法总体上是否正确?

更新

在我改用 push 之后,问题似乎出现在 /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 });
    }
  }
}

出于某种原因,当调用 push 时,_schema 对象未定义,这导致了异常。我不确定这是一个错误,还是有其他东西没有被调用,否则会初始化 _schema 属性?

答案#1

我不确定你在添加子文档时在做什么?你应该只是将它作为一个 POJO 添加。

以下代码已经过测试,运行良好。

async function addNewSeat(planeId: string, seat: ISeat) {
  let plane = await PlaneModel.findById(planeId);
  plane.seatChart.push(seat);
  await plane.save();
}

然后像下面这样调用它:

let plane = await PlaneModel.create({flightNumber:"AR44"});
await addNewSeat(plane.id, {
     travelerId:"x", 
     seatClass:"business", 
     row:4, 
     section:9, 
     hasBoarded:true
});
await addNewSeat(plane.id, {
     travelerId:"y", 
     seatClass:"economy", 
     row:42, 
     section:1, 
     hasBoarded:true
});

答案#2

我找到了答案。我最终不得不将创建数据库连接的逻辑从一个单独的库移到主项目的 inversify.config.js 文件中,并将 mongoose 连接注入到每个存储库中。这似乎解决了问题。