'Child Reference is undefined when executing a callback in parent - NodeJs Typescript

I'm trying to write a quite simple PubSub Mock (pls don't judge) and I've encountered a quite weird behavior.

I basically have three classes, a parent and two children. The point is that they have to communicate with each other, but, for some reason they're losing the reference (commented in FakePubSub):

class FakePubSubTopic {
  private readonly topicName: string;
  private readonly notify: (topicName: string, ...args: any[]) => void;

  constructor(topicName: string, notify: (topicName: string, ...args: any[]) => void) {
    this.topicName = topicName;
    this.notify = notify;
  }

  publishMessage(msg: any) {
    this.notify(this.topicName, msg);
  }
}

class FakePubSubSubscription {
  private topicName: string;
  public onEventReceived: ((...args: any[]) => void) | undefined;

  constructor(topicName: string) {
    this.topicName = topicName;
  }

  on(event: string, onEventReceived: (...args: any[]) => void) {
    this.onEventReceived = onEventReceived;
  }
}

export default class FakePubSub {
  _subscription: FakePubSubSubscription | undefined;
  _topic: FakePubSubTopic | undefined;

  private notify(name: string, ...args: any[]) {
    // when topic.publishMessage is called,
    // _subscription doesn't exist at this point (is undefined)
    this._subscription?.onEventReceived?.(args);
  }

  topic(name: string) {
    this._topic = new FakePubSubTopic(name, this.notify);
    return this._topic;
  }

  subscription(name: string) {
    this._subscription = new FakePubSubSubscription(name);
    return this._subscription;
  }
}

To make easier to understand, every time topic.publishMessage is called, that should execute the callback defined inside subscription.on .

jest test (it's suppose to fail, but to execute at least):

it('works', done => {
  const pubSub = new FakePubSub();
  const topic = pubSub.topic('potato');
  const subscription = pubSub.subscription('potato');

  subscription.on('message', messages => {
    const [first] = messages;

    strictEqual('hi', first);

    done();
  });

  topic.publishMessage({
    data: 'hi',
  });
});


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source