0

I am trying to do function chaining in a Javascript class by returning this after each method, but somehow, it does not work..:

let sql = require('mssql');
let {logger} = require('../utils/logger');
let config = require('config');
//mssql_stellenanzeigen_config = config.get('stellenanzeigen');
mssql_doublettencheckui_config = config.get('doublettencheckui');


class MSSQLConnectionObject {
    constructor(configuration) {
        this.configuration = configuration; 
        this.connection = undefined;    
        this.requestObject = undefined;  
    }

    async build() {
        let pool;
        try {
            pool = await new sql.ConnectionPool(this.configuration).connect(); 
            console.log("Connection established!: ", pool);
        } catch(e) {
            logger.error("No SQL Database config or wrong config. Can't establish connection to MSSQL Server. " + e);
        }    
        this.requestObject = await new sql.Request(pool);

        return this;
    }

    static async connect(config) {        
        let pool;
        try {
            pool = await new sql.ConnectionPool(config).connect(); 
            console.log("Connection established!: ", pool);
        } catch(e) {
            logger.error("No SQL Database config or wrong config. Can't establish connection to MSSQL Server. " + e);
        }    
        this.requestObject = await new sql.Request(pool);
        return this;
    }

    async getBuchungsquelle() {
        const query = `SELECT * FROM buchungsquelle`;
        return await this.requestObject.query(query).then((result) => console.log(result)).catch(err => console.log(err));
    }
}

module.exports = {
    MSSQLConnectionObject
}

   let query= `select * from buchungsquelle`;  

   let a = new MSSQLConnectionObject(mssql_doublettencheckui_config);
   a.build().getBuchungsquelle();

I get an error:

a.build().getBuchungsquelle();            

TypeError: a.build(...).getBuchungsquelle is not a function

why does this not work? Is there an error in how to return this from my functions?

MMMM
  • 3,320
  • 8
  • 43
  • 80
  • 1
    Well, `build` is asynchronous. You can't call `getBuchungsquelle ` on a Promise. Just use promise chaining. – VLAZ May 21 '19 at 09:45

2 Answers2

2

It doesnt work because your function is Async.

You are not actually returning a instance of MSSQLConnectionObject but a instance of Promise<MSSQLConnectionObject>.

Async Chaining:

Check out this Stackoverflow post to get a nice example of async chaining!

Community
  • 1
  • 1
MauriceNino
  • 6,214
  • 1
  • 23
  • 60
  • thanks, that was the reason... is there a way to avoid async function in a class method, or is there a better approach that resolves the promise somehow in a javascript class method automatically? Or can I just use normal functions without async and just wait for a result to come in? How would you do it? – MMMM May 21 '19 at 09:48
  • 1
    You are doing async operations (db queries). So yes it would be wise to keep the functions async and pass the responsibility of resolving to the actual caller. I would avoid chained functions with async operations. – MauriceNino May 21 '19 at 09:51
  • I probably would have to catch the Promise inside an own class method I guess? And then return or assign the resolved Promise value to a this.someProperty instance inside my class and use that value along? Is something like that correct? – MMMM May 21 '19 at 09:51
  • I added another Stackoverflow post in my answer that shows how to implement async method chaining. Feel free to check it out. – MauriceNino May 21 '19 at 09:54
  • I dont understand your question right now sorry? @user2774480 – MauriceNino May 21 '19 at 09:54
2

TypeError: a.build(...).getBuchungsquelle is not a function

build is an async function. When you say return this, it creates a function which returns a promise that resolves to this, not a function that returns this.

So to use it you would need to wait for the promise to resolve and then call the next function in sequence.

a.build().then( x => x.getBuchungsquelle() )
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • thanks, that was the reason... is there a way to avoid async function in a class method, or is there a better approach that resolves the promise somehow in a javascript class method automatically? Or can I just use normal functions without async and just wait for a result to come in? How would you do it? – MMMM May 21 '19 at 09:48