node.js event listener in another source file
Asked Answered
S

4

9

I am trying to design a scenario where on a particular event getting triggered, I wanted a few listeners to perform some task. Trying to also manage S.R.P of code, I want to have the listeners in a different source file. I want to know if this is possible using event Emitter. Does event emitter only work on a single source file?

var events = require('events');
var em = new events.EventEmitter();

exports.saveScheme = function (req, res) {  

var dal = dalFactory.createDAL(constants.SCHEME);
return new Promise.resolve(dal.PromiseSave(req.body))
    .then(function(data){
        var schemeId = data._id;

        em.addListener('FirstEvent', function (data) {
            console.log('First subscriber: ' + data);
        });
        em.emit('FirstEvent', 'Test event emitter');

    }).catch(function(error){
        console.log(error);
    }); 
};

My other source file is

var emitter = require('events').EventEmitter;
var em = new emitter();

//Subscribe FirstEvent
em.on('FirstEvent', function (data) {
    console.log('First subscriber: ' + data);
});
Sixpence answered 11/5, 2016 at 6:58 Comment(0)
G
16

Every eventEmitter object you create is a new instance so events fired from the first one won't be triggered in the second, so the answer to your question is - no, it's not possible. However, there are other solutions:

I think the best one is to create a centralized common eventEmitter, like so:

//firstFile.js
var common = require('./common');
var commonEmitter = common.commonEmitter;

exports.saveScheme = function (req, res) {  

var dal = dalFactory.createDAL(constants.SCHEME);
return new Promise.resolve(dal.PromiseSave(req.body))
    .then(function(data){
        var schemeId = data._id;

        commonEmitter.addListener('FirstEvent', function (data) {
            console.log('First subscriber: ' + data);
        });
        commonEmitter.emit('FirstEvent', 'Test event emitter');

    }).catch(function(error){
        console.log(error);
    }); 
};



//secondFile.js
var common = require('./common');
var commonEmitter = common.commonEmitter;

//Subscribe FirstEvent
commonEmitter.on('FirstEvent', function (data) {
    console.log('First subscriber: ' + data);
});


//common.js
var events = require('events');
var em = new events.EventEmitter();
module.exports.commonEmitter = em;

But if you want the source file to "know" each other - You can do something like this:

//firstFile.js
var events = require('events');
var em = new events.EventEmitter();

exports.saveScheme = function (req, res) {  

var dal = dalFactory.createDAL(constants.SCHEME);
return new Promise.resolve(dal.PromiseSave(req.body))
    .then(function(data){
        var schemeId = data._id;

        em.addListener('FirstEvent', function (data) {
            console.log('First subscriber: ' + data);
        });
        em.emit('FirstEvent', 'Test event emitter');

    }).catch(function(error){
        console.log(error);
    }); 
};
exports.emitter = em;



//secondFile.js
var firstFile = require('./firstFile');
var firstFileEmitter = firstFile.emitter;

//Subscribe FirstEvent
firstFileEmitter.on('FirstEvent', function (data) {
    console.log('First subscriber: ' + data);
});
Glyptics answered 11/5, 2016 at 7:25 Comment(4)
Thanks a ton for the insight.Sixpence
Hi Gilad, I tried example 2, I created 2 js files without any logic, just did and em.emit and did a exports.emitter.In the second file I did not make any changes. The console.log of the second file was not called. Any idea on what I was missingSixpence
Can you please attach your code somehow(as comment or in new question)?Glyptics
I could not fit it in a comment, so I added it as an answer belowSixpence
S
4

The event listener and emitter can be in two different files. Please see a simple example below:

The first file, let's call it eventEx.js

 var EventEmitter = require('events').EventEmitter

   var myEmitter = new EventEmitter();

   myEmitter.on('print', (arg) => {
    console.log(arg);
   })

   exports.myEmitter = myEmitter

And the second file is as following:

var emitter = require('./eventEx.js')
var printEmitter = emitter.myEmitter

printEmitter.emit('print', 'how was Dunkirk?')
printEmitter.emit('print', 'Dunkirk was awesome!!')
Suspense answered 21/8, 2017 at 7:21 Comment(1)
but you are importing eventex in the other file, the solution is there are 2 files that dont import each other but have eventemitter common between both, is that possiblePhonogram
M
2

So this is how I use in my testing. I use it with Class semantics

One caveat to note that is, it is always required to register a listener before an event is emitted, because when an event is emitted, it looks for already registered set of listeners and then emits the flow over there.

//emitter.js
// The core module events has EventEmitter class which we are going to make use of
// note that we are not going to use that explicitly but by means of another class

const EventEmitter = require('events');

Class EventEmitterClass extends EventEmitter{
    emitterMethod(){
      this.emit('testEventEmitted', {obj:'testString object'});
    }
}

module.exports = EventEmitterClass; // we export the module with the objectInstance

//listener.js
// now import the emitter.js and we get back a class - EventEmitterClass
const EventEmitterClass = require('./emitter.js');//give the actual path of js
const eventEmitterObj = new EventEmitterClass();

//now it is mandatory to register the listener before we even think of calling the //emitter method
eventEmitterObj.addListener('testEventEmitted', res => {
   console.log('this is the result from the emitted event:', res);
});

//now call the method that emits the event in the class
eventEmitterObj.emitterMethod();

Now run the listener.js -> node listerner.js

Apologies, if I have explained things way too elaborate

Manymanya answered 13/11, 2018 at 13:39 Comment(0)
M
0

just another example of node.js event listener in another source file typescript styles.

// file 1 (whatever.ts)
import EventEmitter from "events";
const MyEvent = new EventEmitter();
...
// somewhere fire event 
MyEvent.emit('push', 'message', {
  data: somedata
})
// end of file
export const MyEvents = MyEvent;

then in file 2

 // note the .js as eslint will cry 
 import { MyEvents  }  from '../whatever.js'
...
MyEvents.on('push', function(event, data) {
  console.log(event);
  console.log(data);
 // do stuff
});
Moidore answered 2/8, 2022 at 23:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.