简体   繁体   中英

Access class properties outside of mqtt callback scope

I am using npm-mqtt to get data from another mqtt broker.

On each message received I want to add the data to the class/component array property.

But I cannot access the class or its properties. Instead the scope says I am in the mqtt client class object.

Here is a code example:

this.mydata: Array<any> = [];

private fetchWithMqtt(){
var client = mqtt.connect('ws://' + this.ip + ":" + Number(this.port) + "/mqtt");
        // set callback handlers
        client.on('close', this.onConnectionLost);
        client.on('message', this.onMessageArrived);
        client.on('connect', this.onConnect);
}

private onMessageArrived(topic, message) {
        let tempDataset = JSON.parse(message).dataset;
            this.mydata.push({ //this.mydata is undefined because this = mqtt-client
                x: tempDataset[0],
                y: tempDataset[1]
            });

How can I push data to my class property outside this scope?

Using .bind(this) , you can make sure this doesn't change when your events are called.

Your code will now look like:

this.mydata: Array<any> = [];

private fetchWithMqtt(){
    var client = mqtt.connect('ws://' + this.ip + ":" + Number(this.port) + "/mqtt");
    // set callback handlers
    client.on('close', this.onConnectionLost.bind(this));
    client.on('message', this.onMessageArrived.bind(this));
    client.on('connect', this.onConnect.bind(this));
}

private onMessageArrived(topic, message) {
    let tempDataset = JSON.parse(message).dataset;
    this.mydata.push({
        x: tempDataset[0],
        y: tempDataset[1]
    });

But what if you need to access the client within the event handler? Well then you can still use bind, but prepend mydata to the event handler and take it in as an argument.

Your code now becomes:

this.mydata: Array<any> = [];

private fetchWithMqtt(){
    var client = mqtt.connect('ws://' + this.ip + ":" + Number(this.port) + "/mqtt");
    // set callback handlers
    client.on('close', this.onConnectionLost.bind(client, this.mydata));
    client.on('message', this.onMessageArrived.bind(client, this.mydata));
    client.on('connect', this.onConnect.bind(client, this.mydata));
}

private onMessageArrived(mydata, topic, message) {
    let tempDataset = JSON.parse(message).dataset;
    mydata.push({ // this == client
        x: tempDataset[0],
        y: tempDataset[1]
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM