How do I modify the value of an external scope variable inside a callback in nodejs

Good afternoon.
I got this Alexa skill class, inside this class I send and receive messages using mqtt. Unfortunately for this library, the mqtt message needs a callback. Here is my code:

export class Launch implements RequestHandler {
    private readonly options = {
        host: 'host',
        port: 8883,
        protocol: 'mqtts',
        username: 'user',
        password: 'password'
    }

    private readonly mqttClient
    private listener: any
    private delayedPromise: any

    // @ts-ignore
    public constructor(private readonly skillHelper: SkillsHelperInterface) {
        this.mqttClient = mqtt.connect(this.options)
        this.mqttClient.on("connect",function() {
            console.log("connect");
        });
    }

    public canHandle(handlerInput: HandlerInput): Promise<boolean> | boolean {
        return this.skillHelper.isType(handlerInput, RequestTypes.Launch.toString())
    }

    public async handle(handlerInput: HandlerInput): Promise<Response> {
        this.waitForMessage(handlerInput, this.mqttClient, this.delayedPromise)

        this.mqttClient.publish("my/test/topic/publisher", "Hello")

        await this.delay(2000)

        return handlerInput.responseBuilder
            .speak(speechText)
            .reprompt(speechText)
            .getResponse()
    }

    waitForMessage(handlerInput: HandlerInput, mqttClient: MqttClient) {
        this.listener = function(topic: any, message: any) {
            // I want to update this class variable
            this.speechText = message.toString()
        }
        mqttClient.on("message", this.listener);
        mqttClient.subscribe("my/test/topic/subscriber");
    }

    delay(ms: number) {
        return new Promise( resolve => setTimeout(resolve, ms) );
    }
  }

I have this variable called: “this.speechText” which I want to update once the listener is called, but once it exits the listener it doesn’t have the value assigned in the listener. I have also tried passing it into the method that contains the listener but it didn’t work.
Is there anything I can do to update an outer-scope variable inside a callback?

Thanks in advance

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

This problem happens because you are in a different scope when you are using this.

To solve the problem, you only need to change the listener function to an fat arrow function., like this:

this.listener = (topic: any, message: any) => {
   // I want to update this class variable
   this.speechText = message.toString()
};

Using an arrow function, the this references to a one-up level scope (if exists). Of course, an alternative is using a helper variable to point to the object and not to the function:

const _that = this; // Helper variable
this.listener = function(topic: any, message: any) => {
   // I want to update this class variable
   _that.speechText = message.toString()
};

But I recommend you to use the first option.

If you need more information, check to docs on mdn: Fat Arrow Function


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x