3

I have an application where i have a Client class, that needs to be executed with different configurations for each user when i receive a message on discord(It's a chat application having its own API calls for checking for new messages etc). I have initialized the obj constructor whenever i receive a new message with new configurations for that user, but the problem is when i receive multiple messages at the same time, only the latest user's configurations are used for all the client objects created. Attaching sample code from the application:

Wait for message code:

const app = require("./Client")
const app2 = require("./MyObject")

bot.on('message', async (message) => {

    let msg = message.content.toUpperCase(), pg;
    let client = await new app2.MyObject();

    //set all such configurations
    config.a = "valuea";

    // initialize my 
    pg = await new app.Client(config, client);

    let result = await pg.Main(bot, message, params).then((result) => {
        // Do stuff with result here
    });
});

Client class:

class Client {

    constructor(config, client) {
        this.config = config;
        this.client = client;
    }

    async Main(bot, message, params) {
        let result = {};
        this.client.setProperty1("prop");
        await this.client.doSOmething();
        result = await this.doSOmethingMore(message);
        this.client.doCleanUp();
        return result;
    }
}

I had also tried initializing the obj constructor in the Client class, but even that fails for some reason.

Any suggestions how Can i correct my code?

Adil
  • 817
  • 1
  • 8
  • 27
  • 2
    await / async only work with Promises. You're calling await on a constructor (which also doesn't return a Promise, nor can it afaik). Further, you don't await something and also call `.then()`. As it stands, it's really hard to tell what you're trying to do, as you don't even have a MyObject but you initialize one. Hard to correct code under the circumstances. – Paul Jan 30 '18 at 15:35
  • `this.config = config;` ... `config.a = "valuea";` .... You can't reuse the same config object, you need to create a new one for each client. – Roland Starke Jan 30 '18 at 15:37
  • Is `pg` deliberately a global variable? – Bergi Jan 30 '18 at 16:03
  • Updated code @Paul and Berrgi. – Adil Jan 30 '18 at 16:12

2 Answers2

2

You don't need to use .then and await at the same time.

bot.on('message', async (message) => {

    let msg = message.content.toUpperCase();
    let client = await new MyObject();

    //set all such configurations
    config.a = "valuea";

    // initialize my 
    pg = new app.Client(config, client);

    let result = await pg.Main(bot, message, params);
    // Do stuff with result here
    console.log(result);
});

(You don't need to use await at constructor call because it is not an async method)

note: async-await will work on higher version of node than 7.6

If you want to use .then:

bot.on('message', (message) => {
    let msg = message.content.toUpperCase();
    new MyObject().then(client => {
        //set all such configurations
        config.a = "valuea";

        // initialize my 
        pg = new app.Client(config, client);

        pg.Main(bot, message, params).then(result => {
            // Do stuff with result here
            console.log(result);
        });
    });
});
Peter Kota
  • 8,048
  • 5
  • 25
  • 51
2

It's difficult to be certain, since you don't include the MyObject code, but generally it's a bad practice to return a promise from a constructor.

Further, if you don't do it right, then whatever that promise resolves to might not in fact be the Client that your calling code expects.

Paul
  • 35,689
  • 11
  • 93
  • 122