tunoandsuno
tunoandsuno

Reputation: 99

JavaScript callback or observer

This is a general question about javascript. What I want to achieve but I don't know if it's possible is the following.

I want to write a javascript library that contains an object. So by using this javascript library I want to instanciate the object from another javascript file by doing:

myObject = new myObject();

I achieved that by writing a function in my javascript library:

function myObject() {
    //init object logic
}

The thing is that now I want to be able to listen to different events of that object from the javascript file where I instansciated the object before. something like:

myObject = new myObject();

myObject.on('connection', function(conn) {
             conn.on('data', function(data){

                    console.log("conn on data");

                });

                conn.on('error', function(data){

                    console.log("conn on error");

                });

            });

How can I achieve this in javascript? I was thinking about callbacks but I can't figure out the way.

Upvotes: 0

Views: 651

Answers (2)

Chand Ra
Chand Ra

Reputation: 69

//library

      function myObject() {
         //init object logic
      }

      myObject.prototype.attach=function(eventType,callBack){
          //default event
          document.addEventListener(eventType,callBack);
           ......

            //custom event code
            var event = new Event('connection');

            // Listen for the event.
            document.addEventListener('connection', function (e) { ... }, false);

      }

//userFile

      myObject = new myObject();

      myObject.attach("click",clikeMe);
      function clickMe(eventObject){
        .......
        ......
       }

// to dispatch custom event

        document.dispatchEvent(event)

Upvotes: 1

PeterMader
PeterMader

Reputation: 7285

You're looking for a EventEmitter which you could implement this way:

class EventEmitter  {
  constructor () {
    this.events = {};
  }
  on (channel, cb) {
    if (Array.isArray(this.events[channel])) {
      this.events[channel].push(cb);
    } else {
      this.events[channel] = [cb];
    }
  }
  emit (channel, ...args) {
    if (Array.isArray(this.events[channel])) {
      this.events[channel].forEach(cb => cb.apply(null, args));
    }
  }
}

Your class can inherit from EventEmitter:

class MyClass extends EventEmitter {
  constructor () {
    super();
    // do initialization
  }
}

And now, you can instantiate your class:

var myObject = new MyClass();
myObject.on('event', function (a, b) {
  console.log('Event A was emitted: ', a + b); 
});
myObject.emit('event', 123, 456); // "Event A was emitted: 579"

Working example:

class EventEmitter  {
  constructor () {
    this.events = {};
  }
  on (channel, cb) {
    if (Array.isArray(this.events[channel])) {
      this.events[channel].push(cb);
    } else {
      this.events[channel] = [cb];
    }
  }
  emit (channel, ...args) {
    if (Array.isArray(this.events[channel])) {
      this.events[channel].forEach(cb => cb.apply(null, args));
    }
  }
}

class MyClass extends EventEmitter {
  constructor () {
    super();
    // do initialization
  }
}

var myObject = new MyClass();
myObject.on('event', function (a, b) {
  console.log('Event A was emitted: ', a + b); 
});
myObject.emit('event', 123, 456); // "Event A was emitted: 579"

Note that I used a few new features, for example the spread operator (...) and the new class syntax. Of course, you can also achieve the same using the old function and prototype way.

In your code, you have the line

myObject = new myObject();

Don't do that. You assign the new instance to the variable that contains the constructor, losing access to that constructor.

NodeJS has its own EventEmitter class. You can access it using:

var EventEmitter = require('events').EventEmitter;

Upvotes: 3

Related Questions