简体   繁体   中英

expressjs with Typescript mongoose populating

Hello i am trying to Populate two documents in my Express project. i am creating a Classroomschema , and it has an ref to the instructorschema.

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;

i created an interface of every of my Schemas. then i created an interface Request with the type of the interface Instructor

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

export interface RequestWithInstructor extends Request {
    instructor: Instructor;
}

i call the interface in my classRoom controller as i want to add a classroom with a controller , on the console i get the mistake UnhandledPromiseRejectionWarning: TypeError: Cannot read property '_id' of undefined. i want to know if someone can help me. this is the code

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

The line that is currently throwing the error is:

const instructorid = req.instructor._id;

This is because req is not actually a RequestWithInstructor , but a Request provided to you by express. You need to extract the body from it before continuing with your logic.

Hence, the signature should be:

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

Assuming that addClassRoom is a method called by a POST or PUT API call, you will need this line to happen before extracting the _id field.

const classbody = req.body;

Assuming that the body is expected to be a JSON object that conforms to the IClassRoom interface, you could either cast the type and then validate, like

const classRoom = req.body as IClassRoom;

or you could turn the interface into a class with a constructor (though that might not work well with Mongoose), and ideally add a validate method that you would then call from the controller, like:

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

Then you can fetch the instructorId like classRoom.instructor._id if that's where it's expected to be in the JSON body.

Your API controller function's job should be to take in JSON and validate it before it can do the Mongoose interaction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM