2

This is a follow-up to my previous SO question. In that question, I've defined an index.js file that includes an on event handler. I've since updated the index.js file to look like this:

index.js

const EventEmitter = require('events');
const Student = require('./student');
const Whiteboard = require('./whiteboard');

class Classroom {
  constructor() {
    this.whiteboard = new Whiteboard();
  }

  async function start() {
    eventEmitter.on('newListener', (event, listener) => {
      console.log(`Added ${event} listener.`);
    });

    eventEmitter.on('handRaised', (question) => {
      console.log(question);
      this.whiteboard.write(question);
    });

    for (let i=0; i<10; i++) {
      let student = new Student(`Student #${i+1}`);
      student.attend();
    }
  }
}

When I run my app, the line with this.whiteboard.write(question); generates an error. That error is: Cannot read property 'write' of undefined. I've confirmed that this.whiteboard is undefined. My question is, how do I get access to class properties on events?

Thank you!

Some User
  • 5,257
  • 13
  • 51
  • 93

2 Answers2

0

There shouldn't be a problem with using this.whiteboard, but your class definition is strange, actually I would expect SyntaxError by the method definition.

Try to change your code like this:

const EventEmitter = require('events');
const Student = require('./student');
const Whiteboard = require('./whiteboard');

const eventEmitter = new EventEmitter(); /* create an emitter instance */

class Classroom {
  constructor() {
    this.whiteboard = new Whiteboard();
  }

  async start() { /* no 'function' here */
    eventEmitter.on('newListener', (event, listener) => {
      console.log(`Added ${event} listener.`);
    });

    eventEmitter.on('handRaised', (question) => {
      console.log(question);
      this.whiteboard.write(question);
    });

    for (let i=0; i<10; i++) {
      let student = new Student(`Student #${i+1}`);
      student.attend();
    }
  }
}

EDIT: instancing of EventEmitter

ttulka
  • 10,309
  • 7
  • 41
  • 52
  • I think it should be this way: `const EventEmitter = require('events'); const eventEmitter = new EventEmitter();` and there is nothing wrong with `async function xy()`. – Daniel W. Mar 19 '19 at 12:47
  • @DanFromGermany I can agree with the first part (I didn't take a look at the referenced question), but according the second part, you say this `class A { async function xy(){} }` is a valid JavaScript code? – ttulka Mar 19 '19 at 12:51
  • @DanFromGermany But it's inside a class definition! Take a look at [doc](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes). – ttulka Mar 19 '19 at 12:54
  • 1
    You are right, just found it! I think OP's code and his issue do not fit together. The code he presents is not the code he runs. – Daniel W. Mar 19 '19 at 12:55
-1

In the callback of any event you your this never points to your class. try this.

var self = this;
eventEmitter.on('handRaised', (question) => {
  console.log(question);
  self.whiteboard.write(question);
});
Harish
  • 1,841
  • 1
  • 13
  • 26
  • Not quite correct with [arrow function syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions): An arrow function expression is a syntactically compact alternative to a regular function expression, although **without its own bindings to the `this`**, `arguments`, `super`, or `new.target` keywords. – Daniel W. Mar 19 '19 at 12:14