1

I got two classes; authenticationRoutes.ts and authenticationController.ts. In authenticationRoutes I'm calling 'authenticationController.test', the 'authenticationController.test' method calls 'authenticationController.generateAccessAuthToken' method. Whenever I do this I get the following Error: Unhandled rejection TypeError: Cannot read property 'generateAccessAuthToken' of undefined

authenticationRoutes.ts
import { authenticationController } from '../controllers/authenticationController';

        //TEST ROUTE
        this.router.get('/users',  authenticationController.test);

authenticationController.ts


public test(req: Request, res: Response) {
        dbSequelize().User.findAll({
            where: {
                id: '0'
            },
            attributes: ['id']
        }).then((user: UserInstance[]) => {
            this.generateAccessAuthToken('0').then((response: any) => {
                console.log(response);
                res.send(response);
            });
        })
    }


generateAccessAuthToken(_id: any) {
        return new Promise(async (resolve, reject) => {
            await jwt.sign({ id: _id }, SECRET_KEY as string, function (err: Error, token: any) {
                if (err) {
                    reject(err);
                } else {
                    resolve(token);
                }
            })
        })
    }

I want to be able to do what I described without receiving an error.

2 Answers 2

4

I think this will do the trick:

this.router.get('/users', authenticationController.test.bind(AuthenticationController));

Basically, when you have a class A with a method b, if you pass around A.b like:

const a = new A();
const b = a.b;
b(); // now 'this' is lost, any reference to `this` in b() code would be undefined

You are passing only the function. It has nothing to do with the A class now, it is just a function.

So, among other things, you can use bind to explicitly set the this context for a function:

const a = new A();
const b = a.b.bind(a);
b(); // so now b() is forced to use a as this context

I bet there are tons of duplicates about your issue, but I couldn't find anyone fast because the search is tricky (this binding in js has A LOT of issues).

Hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

when i instantiate the controller class, it says that the class is not a constructor
1

I faced the same issue and solved it :

public test = (req: Request, res: Response) => {
        dbSequelize().User.findAll({
            where: {
                id: '0'
            },
            attributes: ['id']
        }).then((user: UserInstance[]) => {
            this.generateAccessAuthToken('0').then((response: any) => {
                console.log(response);
                res.send(response);
            });
        })
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.