【问题标题】:expressjs with Typescript mongoose populating使用 Typescript mongoose 填充的 expressjs
【发布时间】:2020-05-02 13:26:25
【问题描述】:

您好,我正在尝试在我的 Express 项目中填充两个文档。我正在创建一个 Classroomschema ,并且它有一个针对讲师模式的参考。

import * as mongoose from 'mongoose';
const Schema = mongoose.Schema;
import { IClassRoom } from '../interface/IClassRoom';

const ClassRoomSchema = new Schema({
    instructor: {
        ref: 'Instructor',
        type: Schema.Types.ObjectId
    },
    classRoomName: {
        type: String,
        required: true
    },
    classRoomDescription: {
        type: String,
        required: true
    },
    creationDate: {
        type: Date,
        default: Date.now
    },
    classRoomGenre: {
        type: String,
        required: true
    },
    classRoomSkills: {
        type: String,
        required: true
    },
    classRoomVideo: {
        type: String,
    },
    classRoomLevel: {
        type: String
    }
});

const ClassRoomModel = mongoose.model<IClassRoom>('Classroom', ClassRoomSchema);
export default ClassRoomModel;

我为我的每个模式创建了一个接口。然后我用接口 Instructor 的类型创建了一个接口 Request

import { Request } from 'express';
import { Instructor } from './IInstructor';

export interface RequestWithInstructor extends Request {
    instructor: Instructor;
}

我在我的 classRoom 控制器中调用接口,因为我想添加一个带控制器的教室,在控制台上我收到错误 UnhandledPromiseRejectionWarning: TypeError: Cannot read property '_id' of undefined。我想知道是否有人可以帮助我。 这是代码

import { Request, Response } from 'express';
import ClassRoomModel from '../model/ClassRoomModel';
import InstructorModel from '../model/InstructorModel';
import { RequestWithInstructor } from '../interface/RequestC';

export class ClassRoomController {

    public getAllClassRoom = async (req: Request, res: Response) => {
        const classRoom = await ClassRoomModel.find()
        res.json(classRoom);
    }


    public addClassRoom = async (req: RequestWithInstructor, res: Response) => {

        const instructorid = req.instructor._id;

        const classbody = req.body;

        const instructor = await InstructorModel.findById(instructorid);

        const newClassRoom = new ClassRoomModel({
            ...classbody,
            classRoomVideo: req.file.path,
            instructor: instructor
        });

        const savedClassRoom = await newClassRoom.save();

        res.json(savedClassRoom);
    }

【问题讨论】:

    标签: node.js mongodb typescript express mongoose


    【解决方案1】:

    当前抛出错误的行是:

    const instructorid = req.instructor._id;
    

    这是因为req实际上并不是RequestWithInstructor,而是通过快递提供给您的Request。在继续执行逻辑之前,您需要从中提取 body

    因此,签名应该是:

    public addClassRoom = async (req: Request, res: Response)
    

    假设 addClassRoom 是由 POST 或 PUT API 调用调用的方法,您需要在提取 _id 字段之前执行此行。

    const classbody = req.body;
    

    假设 body 应该是一个符合IClassRoom 接口的 JSON 对象,您可以转换类型然后验证,例如

    const classRoom = req.body as IClassRoom;
    

    或者您可以将接口转换为具有构造函数的类(尽管这可能不适用于 Mongoose),并在理想情况下添加一个您将从控制器调用的验证方法,例如:

    const classRoom = new ClassRoom(req.body);
    if (!classRoom.validate()) {
       throw new Error('Invalid ClassRoom object');
    }
    

    然后,您可以像 classRoom.instructor._id 一样获取 instructorId(如果它是 JSON 正文中的预期位置)。

    您的 API 控制器函数的工作应该是在执行 Mongoose 交互之前接收 JSON 并对其进行验证。

    【讨论】:

    • 是的,谢谢它的工作,它保存了id,但填充仍然不起作用,它只显示教练的id,而不是洞教练对象
    • 尝试 const model = new ClassRoomModel({ ... req.body}); 从请求正文中填充 Mongoose 模型对象。
    猜你喜欢
    • 2015-08-07
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 2017-10-29
    • 2019-01-31
    • 2015-09-13
    相关资源
    最近更新 更多