0

I have seen other similar questions, but they most seem to to suggest adding this, but I get the error despite having this:

When I run the code below I get:

TestDB.listOrgTests: Error:  TypeError: Cannot read property 'listTests' of undefined
    at /node/classes/TestDB.class.js:201:29
    at new Promise (<anonymous>)
    at TestDB.listOrgTests (/node/classes/TestDB.class.js:189:14)
    at /node/index.js:116:22
    at /node/index.js:118:6
    at Layer.handle [as handle_request] (/node/node_modules/express/lib/router/layer.js:95:5)
    at next (node/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/node/node_modules/express/lib/router/route.js:114:3)
class TestDB {

  dbc = null;
  constructor() {
    console.log('new USerDB');
    this.dbClass = require('./db.class');
    this.db = new this.dbClass.db();
    this.dbc = this.db.dbConn;
  }

  async listTests(sql, id) {
    console.log('/listTests: ', id);

    var dbc = this.dbc;
    const ts = this.TestClass;
    var ta = new Array();

    return new Promise(async function(resolve, reject) {

      try {

        var values = [id];
        dbc.query(sql,
          values,
          function(err, row) {
            if (err) {
              throw err;
            }
            console.log("TestDB.listTests: Queried ID: " + id + " " + row.length + " rows");
            ta = [];
            for (var i = 0; i < row.length; i++) {

              // do Stuff

            }
            console.log('returned test array: ', ta);
            return resolve(ta);
          });
      } catch (err) {
        console.error("TestDB.listTests: Error: ", err);
        return (reject);
      }
    })
  }

  async listOrgTests(orgID) {
    console.log('/listOrgTests: ', orgID);

    const ts = this.TestClass;
    var ta = new Array();

    return new Promise(async function(resolve, reject) {
      const sql = `
             SELECT *
             FROM tests
             WHERE org_id = ?         
             ORDER BY test_cdate DESC
             `;
      try {
        ta = await this.listTests(sql, orgID);//<< ERROR HERE EVEN WITH this.
        return resolve(ta);
      } catch (err) {
        console.error("TestDB.listOrgTests: Error: ", err);
        return (reject);
      }
    })
  }
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
TenG
  • 3,843
  • 2
  • 25
  • 42
  • 1
    The `this` is incorrect since this doesn't point to the TestDB instance, because the Promise's function is not a method of the TestDB class. Use an arrow function `return new Promise(async (resolve, reject) => {` instead to retain `this` from the TestDB – mplungjan Jun 19 '23 at 18:20
  • 1
    [Never pass an `async function` as the executor to `new Promise`](https://stackoverflow.com/q/43036229/1048572)! – Bergi Jun 19 '23 at 18:31

1 Answers1

1

From looks of it, the only change you need to do is replace following regular function:

return new Promise(async function(resolve, reject) {

with arrow function:

return new Promise(async (resolve, reject) => {

Reason is: arrow functions will properly bind with this (i.e. they will pass in this) of the context they were defined (Disclaimer: this is simplified explanation for now).

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
subdeveloper
  • 1,381
  • 8
  • 21
  • Thank you. I must admit I am poking around in the dark a bit, and happened upon the `async` after a huge amount of desperate experimenting till it worked because I need the functions to complete and return data when called, instead of the caller just jumping ahead without waiting. Is there any other potential side effect of the arrow function? – TenG Jun 19 '23 at 19:04
  • It worked. Thanks again. – TenG Jun 19 '23 at 19:15
  • @TenG No in this context there is no side effect of arrow function that you should be concerned about. But as [Bergi](https://stackoverflow.com/users/1048572/bergi) said in his comment to your original question, you passing `async' function to a `new Promise` is an `anti-pattern` (though it works, but u can miss on proper `error handling/rejection`). Read his linked question for details (not willing to take credit by putting his provided link here)! – subdeveloper Jun 21 '23 at 20:30