shivshankar
shivshankar

Reputation: 2135

function to es6 class base style

i'm newie in es6 and eventEmitter both. i've prepare a module in node event base style and now i'm trying to transform as es6 calass style. here it is

// eventStyle.js

const events = require('events');
const util = require('util');

var Customer = function() {
  // console.log(typeof this);
  events.EventEmitter.call(this);
  //    this is only public function
  this.register = function(email, password) {
  var newCustomer = {email:email, password:password}
  this.emit("newRegistation", newCustomer)
  }

  var _validate = function(customer) {
  if(customer.password=='password')
  this.emit("validated", customer)
  else
  this.emit("registationFailed", customer)
  }

  var _insert = function(customer) {
  this.emit("added", customer)
  }

  var _sendEmail = function(customer) {
  this.emit("emailSent", customer)
  }

  var _registationSuccessful = function(customer) {
  this.emit("registationSuccessful", customer)
  }

  this.on("newRegistation", _validate)
  this.on("validated", _insert)
  this.on("added", _sendEmail)
  this.on("emailSent", _registationSuccessful)
}

util.inherits(Customer, events.EventEmitter )

module.exports = Customer

//eventApp.js

const Customer = require('./eventStyle');
customer = new Customer();
// console.log(customer);
customer.on("registationSuccessful", ()=>{
  console.log("well done");
})

customer.on("registationFailed", ()=>{
  console.log("sorry error");
})
console.log(typeof customer.register);
setTimeout(()=>customer.register(), 1000);

//now my es6 based code (not working for me ) of eventStyle.js

const events = require('events');
const util = require('util');

class Customer {
  constuctor(){
  console.log("cons",this);
  events.EventEmitter.call(this);
  this.on("newRegistation", _validate)
  this.on("validated", _insert)
  this.on("added", _sendEmail)
  this.on("emailSent", _registationSuccessful)
  }

  //    this is only public function
  register(email, password) {
  var newCustomer = {email:email, password:password}
  console.log(this);
  this.emit("newRegistation", newCustomer)
  }

  _validate(customer) {
  if(customer.password=='password')
  this.emit("validated", customer)
  else
  this.emit("registationFailed", customer)
  }

  _insert(customer) {
  this.emit("added", customer)
  }

  _sendEmail(customer) {
  this.emit("emailSent", customer)
  }

  _registationSuccessful(customer) {
  this.emit("registationSuccessful", customer)
  }
}
util.inherits(Customer, events.EventEmitter )

module.exports =  Customer

somebody tell what i'm mistaking. thanks in advance

Upvotes: 0

Views: 93

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074008

Five Four main issues:

  1. You've missed out the first 'r' in constructor

  2. You need to use this when referring to object methods

  3. You need to preserve this in callbacks (see How to access the correct this inside a callback?). In this specific case, you don't; EventEmitter's on calls them with this set correctly (reference). If that guarantee weren't provided, you would.

  4. You need extends events on the class line (the more normal thing to do would be to call the import EventEmitter and then use extends EventEmitter).

  5. You don't use this style to call the super constructor with class events.EventEmitter.call(this);. Instead, you call super. You must do so before any use of this.

So the minimal changes version is

class Customer extends events {

and in the constructor:

constructor() { // Added missing 'r' in "constructor"
    super();    // Added
    console.log("cons", this);
    // Removed `events.EventEmitter.call(this);` here
    // On all four of the following, note `this.`
    this.on("newRegistation", this._validate);
    this.on("validated", this._insert);
    this.on("added", this._sendEmail);
    this.on("emailSent", this._registationSuccessful);
}

But, if you don't want the _ methods to be public, there's no need for them to be public; just create them in the constructor:

class Customer {
    constructor() {
        super();
        console.log("cons", this);

        const _validate = customer => {
            if (customer.password == 'password')
                this.emit("validated", customer);
            else
                this.emit("registationFailed", customer);
        };

        const _insert = customer => {
            this.emit("added", customer);
        };

        const _sendEmail = customer => {
            this.emit("emailSent", customer);
        };

        const _registationSuccessful = customer => {
            this.emit("registationSuccessful", customer);
        };

        this.on("newRegistation", _validate);
        this.on("validated", _insert);
        this.on("added", _sendEmail);
        this.on("emailSent", _registationSuccessful);
    }

    //    this is only public function
    register(email, password) {
        var newCustomer = {
            email: email,
            password: password
        }
        console.log(this);
        this.emit("newRegistation", newCustomer)
    }
}

That second form does create separate function objects for each instance, but the overhead of that is quite small. You'd need millions of instances of your class for it to matter.

You don't have to create them separately, you could do:

this.on("newRegistration", customer => {
    if (customer.password == 'password')
        this.emit("validated", customer);
    else
        this.emit("registationFailed", customer);
});

...and so on. But if you did, the function would be anonymous, which is less helpful in stack traces and such if something goes wrong. (Whereas the ones in const _validate = ... form have names.)


About calling super: If you want to pass along constructor parameters, you can do that by using rest notation:

constructor(...args) {
    super(...args);
    // ...
}

Upvotes: 2

Fefux
Fefux

Reputation: 974

Almost done, missing only extends to event emitter and call to super in constructor to initialise super class (if you don't, this doesn't exist) :

const events = require('events');
const util = require('util');

class Customer extends events {
  constructor(){
  super();
  console.log("cons",this);
  this.on("newRegistation", this._validate)
  this.on("validated", this._insert)
  this.on("added", this._sendEmail)
  this.on("emailSent", this._registationSuccessful)
  }

  //    this is only public function
  register(email, password) {
  var newCustomer = {email:email, password:password}
  console.log(this);
  this.emit("newRegistation", newCustomer)
  }

  _validate(customer) {
  if(customer.password=='password')
  this.emit("validated", customer)
  else
  this.emit("registationFailed", customer)
  }

  _insert(customer) {
  this.emit("added", customer)
  }

  _sendEmail(customer) {
  this.emit("emailSent", customer)
  }

  _registationSuccessful(customer) {
  this.emit("registationSuccessful", customer)
  }
}

module.exports =  Customer

Upvotes: 1

Related Questions