Creating a custom event emitter in Node.JS

·

3 min read

Event Emitter in Node.JS

In this blog we will know how to emmit custom events and respond to those events when they are emitted.

Assuming you have some knowledge of JavaScript before moving ahead in this blog.

Create a new file named logEvents.js

In this file we will create an event logger. For that you need to install some npm modules.

Do the installing part by writing the following commands in vs code terminal

npm i uuid
npm i date-fns

Once you are done with installing these two, import some default modules in your logEvent.js file.

const fs = require('fs');
const fsPromises  = require('fs').promises;
const path = require('path');

Now we need an async function to be declared which will log the date and unique id.

const logEvents = async(message) => {
    const dateTime = `${format(new Date(), 'yyyyMMdd\tHH:mm:ss')}`;
    const logItem = `${dateTime}\t${uuid()}\t${message}}`;

    console.log(logItem);

    try{
        await fsPromises.appendFile(path.join(__dirname, 'logs', 'eventLog.txt'))
    }catch(error){
        console.err(error)
    }

}

After putting everything together, we will export our logEvents function. The final result will look like this

const {format} = require('date-fns')  // for data npm
const {v4:uuid} = require('uuid');


const fs = require('fs');
const fsPromises  = require('fs').promises;
const path = require('path');

const logEvents = async(message) => {
    const dateTime = `${format(new Date(), 'yyyyMMdd\tHH:mm:ss')}`;
    const logItem = `${dateTime}\t${uuid()}\t${message}}`;

    console.log(logItem);

    try{
        await fsPromises.appendFile(path.join(__dirname, 'logs', 'eventLog.txt'))
    }catch(error){
        console.err(error)
    }

}

module.exports = logEvents;

Using the logEvents in index.js

The function that we exported need to be imported as a module here in index.js. Unlike modules provided by node, we need to give a relative path while importing the logEvents.

const logEvents = require('./logEvents');

After importing logEvents we will import events and also extend EventEmitter

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}; // taken directly from the docs

As mentioned extending EventEmitter is done as specified in the docs.

The imports are done so now initialize the object and add a listener to the object.

// initialize object

const myEmitter = new MyEmitter();

// add listener for the log event
myEmitter.on('log', msg => {
    logEvents(msg)
})

After this you just need to use the emit method on myEmitter and run the program.

myEmitter.emit('log', 'Log event emitted!');

After running the program you will find an error

No such directory of log files exists so we will put a check on the directory before writing anything in the file.

In the try- catch block of the logEvent.js file update the code like below

try{
        if(!fs.existsSync(path.join(__dirname, 'logs'))){
            await fsPromises.mkdir(path.join(__dirname, 'logs'));
        }
        await part of the code

The final index.js and logEvent.js file will look like this

 -- logEvents.js

const {format} = require('date-fns')  // for data npm
const {v4:uuid} = require('uuid');


const fs = require('fs');
const fsPromises  = require('fs').promises;
const path = require('path');

const logEvents = async(message) => {
    const dateTime = `${format(new Date(), 'yyyyMMdd\tHH:mm:ss')}`;
    const logItem = `${dateTime}\t${uuid()}\t${message}\n`;

    console.log(logItem);

    try{
        if(!fs.existsSync(path.join(__dirname, 'logs'))){
            await fsPromises.mkdir(path.join(__dirname, 'logs'));
        }
        await fsPromises.appendFile(path.join(__dirname, 'logs', 'eventLog.txt'), logItem)

        // testing
    }catch(error){
        console.log(error)
    }

}

module.exports = logEvents;

-- index.js 

const logEvents = require('./logEvents');

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}; // taken directly from the docs

// initialize object

const myEmitter = new MyEmitter();

// add listener for the log event
myEmitter.on('log', msg => {
    logEvents(msg)
})

// we are using the setTimeout method to see the difference between two events clearly. We can also not use the setTimeout method

setTimeout(() => {
    myEmitter.emit('log', 'Log event emitted!');
}, 2000);

You can remove the setTimeout method and the file will still work as it was intended to do.

In the next blog we will know about creating a custom web server without using any Node frameworks.

Thank you for reading this far.