Event Emitters in Node.js
Tags: node, javascript, express
Published: 2021-07-28 12:38:14

---
title: Event Emitters in Node.js
published: true
date: 2021-04-02 00:00:00 UTC
tags: node, javascript, express
canonical_url: https://www.mariokandut.com/how-to-create-and-consume-events-node-js/
---

On the frontend-side of an application the user interactions are handled through events, click events, keyboard events, mouse moving events, etc. In Node.js (backend-side) we can build a similar system using the [events module](https://nodejs.org/api/events.html).

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#what-is-the-event-emitter)What is the Event Emitter?

Much of the Node.js core API is built around event-driven architecture. There objects or emitters emit events that cause a function object or listener to be called. For example, HTTP and TCP servers are an event emitter, a TCP socket is an event emitter, HTTP request and response objects are event emitters.

All objects that emit events are instances of the `EventEmitter` class and expose an `eventEmitter.on()` function so functions can be attached to the named events. Event names are typically **camel-cased**.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#creating-an-event-emitter)Creating an Event Emitter

The `events` module exports an `EventEmitter` constructor, depending on the Node version the `events` module is the `EventEmitter` or you have to deconstruct it.

```
const EventEmitter = require('events');
```

The `EventEmitter` is a `constructor` and to create a new event emitter the constructor has to be called with the `new` keyword.

```
const myEmitter = new EventEmitter();
```

A common usage pattern with `EventEmitter`is inheritance. Look at this article for a refresher on [Inheritance in Javascript](http://localhost:8000/inheritance-in-javascript-and-the-prototype-chain-explained/).

```
class MyEmitter extends EventEmitter {
  constructor(opts = {}) {
    super(opts);
    this.name = opts.name;
  }
}
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#emitting-events)Emitting Events

The created EventEmitter object exposes two methods - `on` and `emit`.

- `emit` is used to trigger an event.
- `on` is used to add a callback function.

To emit an event the `emit` method has to be called:

```
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
myEmitter.emit('event');
```

The first argument of `emit` is the event namespace. We need to know the event namespace to be able to listen to emitted events.

The `eventEmitter.emit()` method allows an arbitrary set of arguments to be passed to the listener functions, like `myEmitter.emit('event', 'a', 'b');`

The following example emits an error event and a close event when the method destroy is called with an error.

```
const EventEmitter = require('events')
class MyEmitter extends EventEmitter {
  constructor (opts = {}) {
    super(opts);
    this.name = opts.name;
  },
  destroy (err) {
    if (err) { this.emit('error', err) }
    this.emit('close');
  }
}
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#listening-for-events)Listening for Events

To listen to an emitted event the event emitter object has a method `addListener` or the alias `on`.

Copy the following code in the Node REPL and execute.

```
const EventEmitter = require('events');

const eventEmitter = new EventEmitter();
eventEmitter.on('close', () => {
  console.log('close event fired!');
});
eventEmitter.emit('close');
```

The output will be `close event fired!`.

Arguments passed to `emit` are received by the listener.

For example:

```
const EventEmitter = require('events');

const eventEmitter = new EventEmitter();
eventEmitter.on('add', (a, b) => {
  console.log('add event fired!');
  console.log(a + b);
});
eventEmitter.emit('add', 1, 2);
```

**Ordering is important**. Event listeners will not react to events if the event is emitted before the listener is added. Event listeners are also called in the order they are registered.

```
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
eventEmitter.on('my-event', () => {
  console.log('1st');
});
eventEmitter.on('my-event', () => {
  console.log('2nd');
});
eventEmitter.emit('my-event');
```

The output from the code above will be `1st` and then `2nd`.

There is a method which can be used to inject listeners to the top `prependListener`.

```
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
eventEmitter.on('my-event', () => {
  console.log('1st');
});
eventEmitter.prependListener('my-event', () => {
  console.log('2nd');
});
eventEmitter.emit('my-event');
```

Now the output will be `2nd` and then `1st`.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#single-use-listener)Single Use Listener

An event can also be emitted more than once. To reduce this the `once` method can be used. It removes its listener after it has been called.

```
const EventEmitter = require('events');
const eventEmitter = new EventEmitter();
eventEmitter.once('event', () => {
  console.log('event fired');
});
eventEmitter.emit('event');
eventEmitter.emit('event');
```

The output `event fired` will only be logged once.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#removing-listeners)Removing Listeners

Listeners can be removed with the `removeListener` method. It takes two arguments the event name, and the listener function.

```
const callback = stream => {
  console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
```

`removeListener()` will remove, at most, one instance of a listener from the listener array. If a single listener has been added multiple times for the specified eventName, then `removeListener()` must be called multiple times to remove each instance.

The `removeAllListeners` method can be used to remove listeners without having a reference to their function. It takes one optional argument, the event name. It is useful if multiple listener for the same event name have been registered.

Emitting an `error` event on an event emitter will cause the event emitter to throw an exception if a listener for the `error` event has not been registered.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#tldr)TL;DR

- The Node.js core API is built around event-driven architecture.
- The `eventEmitter` is a constructor method.
- To emit events the `emit` method has to be used with an event name as an argument.
- To listen to events the alias `on` or `addEventListener` can be used with the event name.
- The event name should be camelCased.

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**.

If you want to know more about **[Node](https://www.mariokandut.com/tags/node)**, have a look at these [Node Tutorials](https://www.mariokandut.com/tags/node).

**References (and Big thanks):**

[JSNAD - Linux Foundation](https://trainingportal.linuxfoundation.org/),[Node.js Docs](https://nodejs.org/api/events.html),[Nodejs.dev](https://nodejs.dev/learn/the-nodejs-event-emitter),