0

I am unable to access objects declared within a class in Typescript from functions. Here's what I have:

export class QUestions {

    credentials:mysqlCredentials.MySQLCredentials;
    sqlConnector:mysql.Mysql;

    constructor() {
        this.credentials = new mysqlCredentials.MySQLCredentials('192.168.249.139', 'dev', 'dev', 'test');
        this.sqlConnector = new mysql.Mysql(this.credentials);
    }

    addQuestion(req, res) {
        var q = ...<Lot of code over here> ; 
        this.sqlConnector.query(q, null);  //Error shown for this line
        res.send();
    }
}

Error:
TypeError: Cannot call method 'query' of undefined

If the code is structured as shown above i.e. the sqlConnector variable is defined in the Typescript class, it throws the error. If I place the sqlConnector outside the Typescript class it works fine. I need to fix this as I need the sqlConnector object inside the class.

export class Questions {

    credentials:mysqlCredentials.MySQLCredentials;

    constructor() {
        this.credentials = new mysqlCredentials.MySQLCredentials('192.168.249.139', 'dev', 'dev', 'test');
        sqlConnector = new mysql.Mysql(this.credentials);
    }

    addQuestion(req, res) {
        var q = ...<Lot of code over here> ; 
        sqlConnector.query(q, null);  //Error shown for this line
        res.send();
    }
}

var sqlConnector;

2 Answers 2

1

Are you calling the class in a new context (for example using an event handler)?

If so, this becomes the context of the event, not the class context. This is a common JavaScript problem that can happen in TypeScript too.

You can solve the scope issue in a number of ways:

Using an arrow function

If you use an arrow function to assign the function to a member on the Questions class, it will always use the class scope.

export class Questions {

    credentials:mysqlCredentials.MySQLCredentials;
    sqlConnector:mysql.Mysql;

    constructor() {
        this.credentials = new mysqlCredentials.MySQLCredentials('192.168.249.139', 'dev', 'dev', 'test');
        this.sqlConnector = new mysql.Mysql(this.credentials);
    }

    addQuestion = (req, res) => {
        var q = ...<Lot of code over here> ; 
        this.sqlConnector.query(q, null);  //Error shown for this line
        res.send();
    }
}

Using call to set the scope context

This alternative solution means the Questions class doesn't need to be concerned about scope - if you call the method from a different scope context, you simply use call to assign the question instance as the scope.

element.onclick = function () {
    questions.addQuestion.call(questions, argA, argB);
};
Sign up to request clarification or add additional context in comments.

Comments

0

It is also possible to assign class instance to variable, which after compilation will remain within module scope:

var scl:QUestions;
export class QUestions {

    credentials:mysqlCredentials.MySQLCredentials;
    sqlConnector:mysql.Mysql;

    constructor() {
        scl = this;
        this.credentials = new mysqlCredentials.MySQLCredentials('192.168.249.139', 'dev', 'dev', 'test');
        this.sqlConnector = new mysql.Mysql(this.credentials);
    }

    addQuestion(req, res) {
        var q = ...<Lot of code over here> ; 
        scl.sqlConnector.query(q, null); 
        res.send();
    }
}

Be aware though, that it might cause some problems if you have many instances of the QUestions class within single module. Still in most cases should work fine.

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.