0

I'm making an app to manage some smart lights in my house.

I've created a really simple Broker class.

import * as aedes from 'aedes';
import * as net from 'net';

export class Broker {

    aedes: aedes.Aedes;
    broker: net.Server;
    port: number;

    constructor(port: number){
        this.aedes = aedes();
        this.broker = net.createServer(this.aedes.handle);
        this.port = port;
        this.broker.listen(this.port, () => {
            console.log('MQTT is listening.');
        });
    }
    
    /** 
     * This is a callback register function
     *
     * Callback function must have a signature of type : function(topic: string, payload: string)
     **/
    onMsgReceived(callback: {(topic: string, payload: string): void}){
        this.aedes.on('publish', (packet, client) => {
            if (packet.cmd != 'publish') return;
            callback(packet.topic, packet.payload.toString());
        });
    }

}

And then, for the example, a Test class.

export Test {
    someVar: string;
    
    constructor(){ }
    
    onMsgReceivedCallback(topic: string, payload: string){
        console.log('Hey, i\'m printed from the test class');
        console.log('And this is some var : ' + this.someVar);
    }
}

And, of course, an index.ts script.

import { Broker } from './broker.ts'
import { Test } from './test.ts'

const broker = new Broker(1883);
const test   = new Test();


broker.onMsgReceived(test.onMsgReceivedCallback);

The problem is that, if in the function test.onMsgReceived I want to call a member of the class like the var someVar, node throw the following error :

TypeError: Cannot read property 'testVar' of undefined

I don't understand how I can go through this error... Do you have an idea ?

Syscall
  • 19,327
  • 10
  • 37
  • 52

1 Answers1

0

You have to bind the this context of the class instance to a method if you'd like to pass that method as a callback. There are a couple of ways to do this in TypeScript.

Defining the method using an arrow function:

export Test {
    someVar: string;

    constructor() {}

    onMsgReceivedCallback = (topic: string, payload: string) => {
        console.log(`someVar: ${this.someVar}`);
    }
}

Or binding the method in the constructor:

export Test {
    someVar: string;

    constructor() {
        this.onMsgReceivedCallback = this.onMsgReceivedCallback.bind(this);
    }

    onMsgReceivedCallback(topic: string, payload: string) {
        console.log(`someVar: ${this.someVar}`);
    }
}
Dmytro
  • 101
  • 3