0

I've made a class in which the constructor is being declared mostly by a mySQL query that looks like that:

constructor(username) {


        this.mysql = require('mysql');

// create a connection variable with the required details
        this.con = this.mysql.createConnection({
            host: "localhost", // ip address of server running mysql
            user: "root", // user name to your mysql database
            password: "", // corresponding password
            database: "db" // use the specified database
        });

        this.username = username;
        this._password = "";
        this.con.query("SELECT * FROM users WHERE username = ?", this.username, function (err, result, fields) {
            if (err) throw err;
            this._password = result[0].password;
        });
    }

get password() {
        return this._password;
    }

The issue is , when I'm declaring the class like that:

const user= require("./user.js");
let bot = new user("user1");
console.log(user.password();

The code first accessing the get and getting undefined , and only after the the query is done.

How can I fix it?

1 Answer 1

1

You can't make a constructor asynchronous, that's not supported by Javascript.

What you can do is create an asynchronous createUser function that returns a user, and modify the constructor of your User class to take the data returned from the database.

Something like:


class User {
    // Synchronous constructor
    constructor(mysqlData) {
        this._password = mysqlData.password;
    }
}

// Asynchronous create user function
function createUser(name, callback) {

    con.query('your query', [], function (err, result) {
        if (err) return callback(err); // Traditional error-first callback
        const user = new User(result[0]);
        callback(null, user);
    }
}

// Create the user and then do something once the user is created
createUser('user1', function (err, user) {
    if (err) throw err;
    console.log(user.password());
});

Unrelated tip: look into Promises and async/await, they are so much nicer to use than callbacks. Then your createUser function would look something like this (notice the await keyword instead of a callback for the query):

async function createUser(name) {
    const result = await con.query('your query', []);
    const user = new User(result[0]);
    return user;
}

And then you can do const user = await createUser('user1'); from another async function (you can only use await inside of an async function).

Keep in mind that for this to work, you need:

  1. A runtime that supports async/await (Node 7.6+ or a modern browser), or Babel to transpile the code so it can run in older runtimes & browsers.
  2. A mysql client that supports promises (there are wrappers on npm for most packages).
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for you answer ! could you give an example of how that would look like with async/await please?
Sure! Added an example to my answer. PS. Don't forget to accept the answer if I've helped you solve your problem :)
Why is the result in the async query is different from the callback query? (the callback gives a good result with all the needed information and the async query gives some wierd data like _events: { error: [Function], packet: [Function], end: [Function], timeout: [Function], 'start-tls': [Function] }, _eventsCount: 5, _maxListeners: undefined, _callback: undefined, _callSite: Error)
For that you'll have to check out the docs of the promise wrapper, they'll probably have some examples of how to use it with await. I know with mysql2/promise you have to do const [result] = await pool.query(), because it returns multiple values so you use destructuring to get the results out. Likely you'll have to do something similar for the library you're using, but it should be explained in the docs of that library.

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.