[Fixed] Express JS: call a method in my class on routing

Issue

I’m creating a MERN Application with Typescript.

I have some problem with this on my class.

With this snippet:

router.post("/create", user.createNewUser);

Is Impossible to call another method of the class user inside at the function createNewUser.

And If I use this snippet:

router.post("/create", (req: Request, res: Response, next: NextFunction) => {
    try {
        user.createNewUser(req, res, next);
    } catch (error) {
        res.json(error);
    }
});

It work properly.

This is my function:

createNewUser(req: Request, res: Response, next: NextFunction) {
    try {
        const { password, username, email, id } = req.body;
        const payload: object = { /* HERE MY JSON */ };
        schema.create(payload, async(err: any, result: any) => {
            const isSended = await this.sendRegistrationEmail(email);
            if (err) throw err;
            if (isSended) {
                res.status(200).json(result);
            } else {
                res.status(500).json('error');
            }
        });

    } catch (error) {
        res.status(500).send(error);
    }
};

The error is:

TypeError: Cannot read property ‘sendRegistrationEmail’ of undefined

I wanna know why with the first solution doesn’t work, and with the second one work.

Solution

The this keyword is tricky. Basically the problem is that when you do

router.post("/create", user.createNewUser);

you’re only passing the value of the createNewUser function, and not the entire user. Since the function is now just a floating value and not attached to the user object, the value of this becomes undefined.

The solution is either

router.post("/create", (...args) => user.createNewUser(...args));

or

router.post("/create", user.createNewUser.bind(user));

Leave a Reply

(*) Required, Your email will not be published