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