What is an event?
An event is a signal that something has happened. When an event(or a signal) is raised, some other action is performed which is referred to as event handling. Event handling mechanism may differ from application to application.
Example, in a desktop application when a button is clicked, it is an event which signals that the button has been clicked. Action which needs to be performed on the button click will be event handling for that event.
Another example is the log in button click event in gmail. When this button is clicked, username and password are sent to the server and verified. Based on the verification result, the user is allowed to login or not.

Raising an event is also called emitting an event.

Events module
Much of node’s functionality is based on the concept of events. Example, its Server object raises(or emits) an event whenever a new client connection is made.
Node has a built in module called Events module which provides event handling functionality to node applications. This module can be loaded using require function with “events” as argument as shown below.

require(‘events’);

EventEmitter class
Node’s Events module is centered around this class. All objects that raise(or emit) events are instances of this class. Event mechanism is based on two actions. One is raising an event and other is handling that event.
EventEmitter class has methods for each of these actions. They are:
1. addActionListener: This method is used for adding an event handler. It takes 2 arguments. First is a string representing the name of event which should be handled by this listener. Second is a function which will be invoked automatically when an event with that name is raised.
2. emit: This method is used for raising an event. It takes a single string argument which is the name of event that is raised.
EventEmitter also has an on method which is same as emit. It has the same signature and performs same function.
Whenever an event is emitted all the listeners registered for that event are invoked in the order in which they are registered.
Example
An example of event handling mechanism in node using EventEmitter class is given below.

const EventEmitter = require('events');

// create an object of event emitter
const event = new EventEmitter();

// add event handler
event.addListener('myEvent', function () {
    console.log('Event raised!!!');
});

// raise event
event.emit('myEvent'); 
// you can also use event.on('myEvent')

First of all, node’s Events module is loaded. Note that the require function in this case returns a class and not an object as in the case of Path or File System modules.
Notice the case of the constant to hold the returned value from require function. It is a class and hence the first letter of each word is in upper case. This is the convention.
Next we need to create an object of EventEmitter class to access its methods. Object is created using new operator.
Once the object is created we can call its addListener and emit methods. Note that the name of event is(and should be) the same in both these methods.
When the above code runs, an event is emitted with the name myEvent and the listener registered to handle that event is invoked.
Output of above code will be.

E:\node>node firstprogram.js
Event raised!!!

Remember that the order of methods is important. That is, addListener should be written before emit.

Multiple event handlers
It is also possible to add more than one event handler functions for the same event. You can add any number of listeners for a particular event using addListener method.
All the functions registered to handle that event are invoked one by one.  In this case, all the event handlers invoked in the order in which they are written. Example,

const EventEmitter = require('events');

// create an object of event emitter
const event = new EventEmitter();

// add event handler
event.addListener('myEvent', function () {
    console.log('Event raised!!!');
});

// add another event handler
event.addListener('myEvent', function () {
    console.log('Event raised again!!!');
});

// raise event
event.emit('myEvent');

Output of above will be

E:\node>node firstprogram.js
Event raised!!!
Event raised again!!!

Event handler functions can also be written using arrow functions introduced in ECMAScript2015 or ES6. With arrow functions you can omit the function keyword. You only need to have the header of function composed of parenthesis and body of the function enclosed between curly braces. Header and body are separated by => as shown below.

// event handler using arrow function
event.addListener('myEvent', () => {
    console.log('Event raised!!!');
});

Event arguments
Often we need to pass some data related to the event raised to the handler function.
Example, if there are multiple buttons on a page, you would want to create a single event handler for all those button click events. For that you need to know which button was clicked so that you can perform appropriate action.
It is possible to supply an object to the event handler function from the event emitter.
emit or on function takes a second argument which is an object of key-value pairs. This object can then be received by the event handler function as shown below.

const EventEmitter = require('events');

// create an object of event emitter
const event = new EventEmitter();

// add event handler
event.addListener('myEvent', function (arg) {
    console.log('Event raised');
    // print event argument
    console.log(arg);
    // access argument value
    console.log(arg['buttonid']);
});

// raise event with event argument
event.emit('myEvent', {buttonid: 'login', index: 1});

Note that the name of parameter in the event handler function is arg. It is not necessary to name it that way. You can choose any name you like such as eventArg, e, event etc.
Above code outputs

E:\node>node firstprogram.js
Event raised
{ buttonid: ‘login’, index: 1 }
login

which is self explanatory.

For a better understanding about javascript objects, refer this article.

Leave a Reply