I'm trying to create a Publisher-Subscriber pattern with Nodejs eventEmitters for my nodejs/express API project. My use-case is fairly simple:
- I want to emit events from various places in my project. For example, emit an event when a new user is created.
- Then I want a single place, where I listen to all the events and decide what actions to take.
This will require a singleton instance of eventEmitter because 'emit' and 'on' calls should happen on the same instance of 'event' object.
To achieve it, this is how my index.js looks:
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
const routes = require('./api/routes')
const EventEmitter = require("events");
const eventEmitter = new EventEmitter();
const eventListeners = require('../src/subscribers/events');
//const eventSubs = new eventListeners();
app.use(eventListeners.eventSubscribers());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.set('eventEmitter', eventEmitter);
app.get('/', (req, res) => res.send('App is working'))
app.use('/api', routes)
app.listen(3000, () => console.log('Example app listening on port 3000!'))
module.exports = {
app
}
This is how my middleware/controller function looks(where I'm emitting event):
const createUser = async (req, res, next) => {
var user = req.body
try {
console.log('in controller');
await newUser(user)
console.log(req.app.get('eventEmitter'));
req.app.get('eventEmitter').emit('USER_CREATED', {email: user.email, name: user.name})
res.status(200).send({success: true});
next()
} catch(e) {
console.log(e.message)
res.sendStatus(500) && next(e)
}
}
And, this is how my event subscriber file looks:
const eventSubscribers = (req) => {
const eventEmitter = req.app.get('eventEmitter');
eventEmitter.on('USER_CREATED', ({ email, name }) => {
console.log('event fired and captured')
})
}
Using this, the event is getting emitted, but the event subscriber is not getting trigerred. I think there is something wrong with the way I'm accessing req/app objects in my subscriber. Also, I'm getting
TypeError: eventListeners.eventSubscribers is not a function
error in my index.js file. Questions I have:
- Is this the right way to create a publisher/subscriber pattern?
- How do I access req/app object instances in my event subscriber?
- What's the best way to make sure event subscriber file is loaded when the app loads?