In this article, we will learn about Defining the AdonisJS Events and Listeners Module, how Adonis supports these Events and Listeners Module, and how to define these Events and Listeners Module.

AdonisJS Events and Listeners

The events module differs from the Node.js native Events module and the AdonisJS event emitter module is created on top of Emittery in the following ways.

  • The events module is asynchronous, whereas the Node.js events module emits events synchronously. So, you can read also the Emittery explanation on this as well for sure.
  • The events module Ability to make events type-safe.
  • The events module Ability to trap events during tests instead of triggering the actual event.

Usage

However, we can define the event listeners inside the start/events.ts file. Also, we can create this file manually or run the following Ace command below.

You can check our previous article: AdonisJS: REST API simple CRUD Operation. IF you want then buy a good, reliable, secure web hosting service  from here: click here

node ace make:prldfile events

# SELECT ALL THE ENVIRONMENTS
Now, open the file that you created newly and write the following below code inside it.

The Event.on method registers as an event listener and it accepts the event name as the first argument, followed by a method to handle the event in the below code.

import Event from '@ioc:Adonis/Core/Event'

Event.on('new:user', (user) => {
console.log(user)
})

You will have to emit this event to trigger the new:user event listener, and you can do it from anywhere inside your application after it has been booted as below code.

import Event from '@ioc:Adonis/Core/Event'

export default class UsersController {
public async store() {
// ... code to create a new user
Event.emit('new:user', { id: 1 })
}
}

Making events type-safe

So, the event listeners and the code that emits the event are usually not in the same place or file.

Therefore, it is a very easy way for some of your code to emit the event and send the wrong data. For example, like below:

Event.on('new:user', (user) => {
console.log(user.email)
})

// There is no email property defined here
Event.emit('new:user', { id: 1 })

Here, you can prevent this behavior by defining the argument’s type for a given event inside the contracts or the events.ts file.

declare module '@ioc:Adonis/Core/Event' {
interface EventsList {
'new:user': { id: number; email: string }
}
}

Now, the TypeScript static compiler will ensure that all Event.emit calls for the new:user event is type-safe as in the below screenshot.

Love to Code? We’re Your Helping Partner, click here for  Buy Our Service

Defining the AdonisJS Events and Listeners Module

Listener Classes

You can also extract the inline event listeners to their dedicated classes as Like controllers and middleware.

However, we can customize the namespace inside the adonisrc.json file, and Conventionally event listeners are stored inside the app/Listeners directory.

So, the customize event listeners namespace is as like:

{
"namespaces": {
"eventListeners": "App/CustomDir/Listeners"
}
}
You can purchase your hosting from Cloudsurph.comCloudsurph hosting is a reliable hosting option for business and personal projects. We offer insight and help on system configuration issues and code errors or bugs.

You can create a listener class by running the following Ace command below the code

node ace make:listener User

# CREATE: app/Listeners/User.ts

Now, open the newly created file and define the following method on the class like below.

import { EventsList } from '@ioc:Adonis/Core/Event'

export default class User {
public async onNewUser(user: EventsList['new:user']) {
// send email to the new user
}
}

Finally, we can bind the onNewUser method as the event listener inside the start/events.ts file.

So, the binding process is similar to a Route controller binding, and there is no need to define the complete namespace as below code

Event.on('new:user', 'User.onNewUser')

Error Handling

Since Emittery emits events asynchronously when you use the Event.emit method and the one way to handle the errors is to wrap your emit calls inside a try/catch block like below

try {
await Event.emit('new:user', { id: 1 })
} catch (error) {
// Handle error
}

However, you should define the error handler only once following the below code

Event.onError((event, error, eventData) => {
// handle the error
})

If you want to know more about AdonisJS Model relationships then please visit AdonisJs main website.

If you enjoyed reading this article and have more questions please reach out to our support team via live chat or email and we would be glad to help you. we provide server hosting for all types of need and we can even get your server up and running with the service of your choice.