DEV Community

Amr Elmohamady
Amr Elmohamady

Posted on • Updated on • Originally published at amrelmohamady.hashnode.dev

Why and how to use the the Node.js Event Emitter in real projects?

The Observer pattern and the Event Emitter

The Observer pattern defines an object (called the subject) that can notify a set of observers (or listeners) when a change in its state occurs.

It can be implemented in OOP by using a class that can register and store listeners in an array and calls them when something happens.

In Node.js it can be implemented using the EventEmitter class which is imported from the events built-in module. It allows to emit and listen for events (with multiple listeners).

EventEmitter Illustration

The EventEmitter is exported from the events core module:

const { EventEmitter } = require("events");
const emitter = new EventEmitter();
Enter fullscreen mode Exit fullscreen mode

The essential methods of the EventEmitter are as follows:

  • on(event, listener): This method allows us to register a new listener (a function) for the given event type (a string).
  • once(event, listener): This method registers a new listener, which is then removed after the event is emitted for the first time.
  • emit(event, [arg1], [...]): This method produces a new event and provides additional arguments to be passed to the listeners.
  • removeListener(event, listener): This method removes a listener for the specified event type.

When to use the EventEmitter

It can be used in backend projects and here's a real example where I used it, In an LMS, when a teacher publishes a new lesson I need to send emails and notifications to all the students that are subscribed to the teacher, so we shouldn't put that code in the publish lesson request so the teacher doesn't wait for the emails and notifications to be sent to get a success response and we separate the publish lesson logic from the emails and notifications part to have clean code by achieving the separation of concerns principle.
Another example is when you need to update a real-time dashboard or to send a notification to your investors when new users signup.

How to use the EventEmitter in real projects

Create this folder structure:

/events
    /subscribers
        /lessons.subscriber.js
        /users.subscriber.js
    /emitter.js
    /index.js
Enter fullscreen mode Exit fullscreen mode

In /emitter.js:
Create a new EventEmitter and export it.

const { EventEmitter } = require("events");

module.exports = new EventEmitter();
Enter fullscreen mode Exit fullscreen mode

In /index.js
Import the created EventEmitter and export it with the events' names.

const EventEmitter = require("./emitter");

module.exports = {
  EventEmitter,
  events: {
    LESSON_PUBLISHED: "LESSON_PUBLISHED",
    NEW_SIGNUP: "NEW_SIGNUP"
  }
};
Enter fullscreen mode Exit fullscreen mode

we can also separate the events' names in a different file but there's no need to.

In subscribers/users.subscriber.js:
Import the events and the EventEmitter instance and listen to the events.

const { events, EventEmitter } = require("../");

EventEmitter.on(events.NEW_SIGNUP, user => {
  // Your logic
}
Enter fullscreen mode Exit fullscreen mode

Now we are done with the listeners part, in your controller or service you can import the EventEmitter instance and the events' names then emit the event and pass the data you want like:

EventEmitter.emit(events.NEW_SIGNUP, user);
Enter fullscreen mode Exit fullscreen mode

Subscribe to my newsletter

I hope you like this article, you can follow the blog if you want more.
My LinkedIn

Discussion (4)

Collapse
urielsouza29 profile image
Uriel dos Santos Souza

how to remove in real projects?

Collapse
amrelmohamady profile image
Amr Elmohamady Author

In such usecases, no need to remove event listeners and once can be used.
But, If you need to remove listeners, you can use removeListener and the listener function should be defined on its own like:

const eventHandler = () => { /* Logic */ };
Eventemitter.on("EVENT_NAME", eventHandler);
EventEmitter.removeListener("EVENT_NAME", eventHandler);
Enter fullscreen mode Exit fullscreen mode
Collapse
amrelmohamady profile image
Amr Elmohamady Author

What do you mean?

Collapse
urielsouza29 profile image
Uriel dos Santos Souza

How to properly remove event listeners in node js eventemitter?