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.
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
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
Event raised
{ buttonid: ‘login’, index: 1 }
login
which is self explanatory.
For a better understanding about javascript objects, refer this article.