扩展CRUD实现的基类时出错

时间:2022-09-02 12:40:00

I am trying to implement a base class in typescript for my node.js application. The idea is that all entities/objects can extend the base class to use for their CRUD.

我试图在我的node.js应用程序的typescript中实现一个基类。我们的想法是所有实体/对象都可以扩展基类以用于它们的CRUD。

Here is the base class:

这是基类:

export class Base {
    Model: any;
    constructor(modelName: object) {
        this.Model = modelName;

    }
    public getAll(req: Request, res: Response) {
        console.log(this.Model);
        this.Model.find({}, (err: Error, result: any) => {
            if (err) {
                res
                    .status(HttpStatus.NOT_FOUND)
                    .send({
                        message: HttpStatus.getStatusText(HttpStatus.NOT_FOUND),
                        error: err
                    });
            }
            res
                .status(HttpStatus.OK)
                .send({
                    message: HttpStatus.getStatusText(HttpStatus.OK),
                    output: result
                });
        });
    }

    public get(params: object, res: Response) {
        this.Model.find(params, (err: Error, result: any) => {
            if (err) {
                res
                    .status(HttpStatus.NOT_FOUND)
                    .send({
                        message: HttpStatus.getStatusText(HttpStatus.NOT_FOUND),
                        error: err
                    });
            }
            res
                .status(HttpStatus.OK)
                .send({
                    message: HttpStatus.getStatusText(HttpStatus.OK),
                    output: result
                });
        });
    }

    public create(params: object, res: Response) {
        console.log(this.Model);
        this.Model.create(params, (err: Error, result: any) => {
            if (err) {
                res
                    .status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .send({
                        message: HttpStatus.getStatusText(HttpStatus.INTERNAL_SERVER_ERROR),
                        error: err
                    });
            }
            res
                .status(HttpStatus.CREATED)
                .send({
                    message: HttpStatus.getStatusText(HttpStatus.CREATED),
                    output: result
                });
        });
    }

    public update(params: object, res: Response) {
        this.Model.update(params, (err: Error, result: any) => {
            if (err) {
                res
                    .status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .send({
                        message: HttpStatus.getStatusText(HttpStatus.INTERNAL_SERVER_ERROR),
                        error: err
                    });
            }
            res
                .status(HttpStatus.OK)
                .send({
                    message: HttpStatus.getStatusText(HttpStatus.OK),
                    output: result
                });
        });
    }

    public delete(params: object, res: Response) {
        this.Model.delete(params, (err: Error, result: any) => {
            if (err) {
                res
                    .status(HttpStatus.NOT_FOUND)
                    .send({
                        message: HttpStatus.getStatusText(HttpStatus.NOT_FOUND),
                        error: err
                    });
            }
            res
                .status(HttpStatus.OK)
                .send({
                    message: HttpStatus.getStatusText(HttpStatus.OK),
                    output: result
                });
        });
    }

    public search(req: Request, res: Response) {

    }

    public filter(req: Request, res: Response) {

    }
}

And the child class is as follows:

子类如下:

class AssetClass extends Base {
    constructor(model: object) {
        model = AssetClassModel;
        logger.debug("creating the assetClass constructor");
        super(model);
    }

    public get(req: Request, res: Response) {
        const params: object = {
            name: req.body.name
        };
        super.get(params, res);
    }

    public create(req: Request, res: Response) {
        logger.debug("creating the asset class");
        const params: object = {
            name: req.body.name,
            manufacturer: req.body.manufacturer,
            category: req.body.category
        };
        super.create(params, res);
    }

    public update(req: Request, res: Response) {
        const params: object = {
            name: req.body.name,
            manufacturer: req.body.manufacturer,
            category: req.body.category
        };
        super.update(params, res);
    }

    public delete(req: Request, res: Response) {
        const params: object = {
            name: req.body.name,
        };
        super.delete(params, res);
    }
}

export const assetClass: AssetClass = new AssetClass(AssetClassModel);

I have defined two routes, create and getAll in my app.ts

我在app.ts中定义了两个路径,create和getAll

app.post("/test", assetClass.create);
app.get("/test", assetClass.get);

When I test my application, I get the following error:

当我测试我的应用程序时,我收到以下错误:

[Node] TypeError: Cannot read property 'Model' of undefined
[Node]     at create (/home/hassaan/apollo-be/rest/dist/controllers/base.controller.js:49:26)
[Node]     at create (/home/hassaan/apollo-be/rest/dist/controllers/assetClass.controller.js:28:15)
[Node]     at Layer.handle [as handle_request] (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/layer.js:95:5)
[Node]     at next (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/route.js:137:13)
[Node]     at Route.dispatch (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/route.js:112:3)
[Node]     at Layer.handle [as handle_request] (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/layer.js:95:5)
[Node]     at /home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:281:22
[Node]     at Function.process_params (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:335:12)
[Node]     at next (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:275:10)
[Node]     at serveStatic (/home/hassaan/apollo-be/rest/node_modules/serve-static/index.js:75:16)
[Node]     at Layer.handle [as handle_request] (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/layer.js:95:5)
[Node]     at trim_prefix (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:317:13)
[Node]     at /home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:284:7
[Node]     at Function.process_params (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:335:12)
[Node]     at next (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:275:10)
[Node]     at app.use (/home/hassaan/apollo-be/rest/dist/app.js:86:5)
[Node]     at Layer.handle [as handle_request] (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/layer.js:95:5)
[Node]     at trim_prefix (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:317:13)
[Node]     at /home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:284:7
[Node]     at Function.process_params (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:335:12)
[Node]     at next (/home/hassaan/apollo-be/rest/node_modules/express/lib/router/index.js:275:10)
[Node]     at app.use (/home/hassaan/apollo-be/rest/dist/app.js:71:5)

From what I can gather from this error, the this.Model in base class is being invoked through an uninstantiated object of the assetClass class, i.e Model of undefined

从我从这个错误中收集到的内容,通过assetClass类的未实例化对象调用基类中的this.Model,即undefined模型

But if I console.log the assetClass object in my app.ts file, I can see that it is a valid defined instance.

但是如果我在app.ts文件中调用asset.log的assetClass对象,我可以看到它是一个有效的已定义实例。

What am I doing wrong?

我究竟做错了什么?

1 个解决方案

#1


2  

In javacript who this is, is decided by the caller, and when you pass in a function to someone, you are passing just the function with no memory of the instance it came from. This is why this is undefined when create is called by the routing engine. To bind an instance to a function you need to use the bind function or use an arrow function:

在javacript中,这是由调用者决定的,当你向某人传递一个函数时,你只传递函数而没有来自它的实例的内存。这就是路由引擎调用create时未定义的原因。要将实例绑定到函数,您需要使用绑定函数或使用箭头函数:

app.post("/test", assetClass.create.bind(assetClass));
app.get("/test", assetClass.get.bind(assetClass));

// Or
app.post("/test", (req, res) => assetClass.create(req, res));
app.get("/test", (req, res) => assetClass.get(req, res));

#1


2  

In javacript who this is, is decided by the caller, and when you pass in a function to someone, you are passing just the function with no memory of the instance it came from. This is why this is undefined when create is called by the routing engine. To bind an instance to a function you need to use the bind function or use an arrow function:

在javacript中,这是由调用者决定的,当你向某人传递一个函数时,你只传递函数而没有来自它的实例的内存。这就是路由引擎调用create时未定义的原因。要将实例绑定到函数,您需要使用绑定函数或使用箭头函数:

app.post("/test", assetClass.create.bind(assetClass));
app.get("/test", assetClass.get.bind(assetClass));

// Or
app.post("/test", (req, res) => assetClass.create(req, res));
app.get("/test", (req, res) => assetClass.get(req, res));