DEV Community

Cover image for Using Events In Node.js The Right Way

Using Events In Node.js The Right Way

Usama Ashraf on November 03, 2018

Before event-driven programming became popular, the standard way to communicate between different parts of an application was pretty straightforwar...
Collapse
 
jochemstoel profile image
Jochem Stoel

I'll flesh it out a bit more by providing some related details.

There are a few differences between the EventTarget in the browser and the EventEmitter from Node.

The EventEmitter class implements on, off and emit to register/unregister/fire events. In the EventTarget of window these are called addEventListener, removeEventListener and dispatchEvent.

The EventEmitter is chainable, the EventTarget in the browser is not.

// this works
emitter.on('user-registered', user => {
  console.log('new user registered!', user)
}).on('message', message => {
  console.log('received message!', message)
})

// this not works
document.body.addEventListener('DOMContentLoaded', console.log).addEventListener('error', console.error)
Enter fullscreen mode Exit fullscreen mode

Although on is chainable, off is not. When you remove an event listener using off You can not add another .off to it. In my opinion this is inconsistent and bad practice but I don't want to debate it.

Using EventEmitter, you simply emit any type of object. In a window, EventTarget.dispatchEvent requires the second argument to be of type Event. This means that in order to emit a new event, in the browser you need to instantiate an Event for it.

document.body.dispatchEvent('ready', new Event('something is ready'))
Enter fullscreen mode Exit fullscreen mode

If you want to deal with events in an even more sophisticated matter then have a look at eventemitter2 on NPM. It normalizes some inconsistencies and adds a few features such as wildcard type event listeners

// this will fire on user.ready, user.disconnect, user.whatever ...
myEvents.on('user.*', data => {
   console.log('something user related happened!', data)
})
Enter fullscreen mode Exit fullscreen mode

But it can be done even better. If this stuff interests you then have a look at my Emitter class which is designed specifically to fill these gaps.

Collapse
 
usamaashraf profile image
Usama Ashraf

Thanks so much for the valuable input Jochem! If you don't mind, I might include eventemitter2 and wild card-based subscriptions in this article and on another platform where I published it.

Collapse
 
jochemstoel profile image
Jochem Stoel

By all means! Sharing is caring.

Collapse
 
chenge profile image
chenge

May I ask a question, how do I fire a event?

Collapse
 
usamaashraf profile image
Usama Ashraf

Hey chenge, firing is just another word for "emitting".

Collapse
 
chenge profile image
chenge

Hi Usama thanks. But sendEmailOnRegistration doesn't work, why?

user = {};
myEmitter.emit('user-registered', user);

myEmitter.on('user-registered', (user) => {
  console.log("listened...");
});

myEmitter.on('user-registered', sendEmailOnRegistration);



Thread Thread
 
chenge profile image
chenge

I see. I must subscribe first.

Collapse
 
spirodonfl profile image
Spiro Floropoulos

This was a good read. You took a somewhat smaller concept and fleshed it out.

Nice work!

Collapse
 
usamaashraf profile image
Usama Ashraf

Thank you!

Collapse
 
_ferh97 profile image
Fernando Hernandez

Using event architecture in our APIs will make them more efficiently? Which are the advantages?

Collapse
 
chenge profile image
chenge

The project is divided handlers and listeners?