Brad
Brad

Reputation: 163262

Cannot extend a class, extra methods undefined

Suppose I have the following class:

import EventEmitter from 'event-emitter';

export default class SharedChannel extends EventEmitter {
  constructor(opts) {
    super();
    console.log('SharedChannel constructor');
  }

  send(event, data) {
    console.log('SharedChannel send');
  }
}

In my application, I try to use that class:

import SharedChannel from './lib/SharedChannel';
const channel = new SharedChannel();
channel.send('sessionData', 'Some session data goes here');

I get the following error:

Uncaught TypeError: channel.send is not a function

Methods from the EventEmitter class do work, but my send method does not. I can, for example, call channel.emit(). Also, I am able to access class methods from within that class constructor. For example, I can call channel.send() right after super(). I'm able to hack around it by calling this.send = function() { ... in the constructor, but of course, this should not be necessary.

This application is being built with Webpack and Babel. In my webpack.config.js, I have the following Babel rule:

{
  test: /\.js$/,
  exclude: /(node_modules|bower_components)/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: ['@babel/preset-env']
    }
  }
}

In .babelrc:

{
  "presets": ["@babel/preset-env"]
}

Versions for packages:

"@babel/core": "^7.0.0-rc.1",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-rc.1",
"@babel/preset-env": "^7.0.0-rc.1",
"babel-loader": "^8.0.0-beta",
"webpack": "^4.16.5",
"webpack-cli": "^3.1.0"

Any advice on how to fix this?

Upvotes: 2

Views: 215

Answers (1)

loganfsmyth
loganfsmyth

Reputation: 161467

You are misusing the API of EventEmitter. It is not meant to be used as a parent class, it is a mixin. If we look at the usage documentation for instance:

var ee = require('event-emitter');

var MyClass = function () { /* .. */ };
ee(MyClass.prototype);

Calling the ee function with the MyClass.prototype mixes the event emitter logic onto the class prototype. Similarly, in your example you'd want

import EventEmitter from 'event-emitter';

export default class SharedChannel {
  constructor(opts) {
    console.log('SharedChannel constructor');
  }

  send(event, data) {
    console.log('SharedChannel send');
  }
}
EventEmitter(SharedChannel.prototype);

Upvotes: 1

Related Questions