# Events And Listeners

ExpressWebJs events provides a simple observer implementation, allowing you to subscribe and listen for events in your application. Event classes are typically stored in the App/Events directory, while their listeners are stored in App/Listeners. Don't worry if you don't see these directories in your application as they will be created for you as you generate events and listeners using Maker console commands.

Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other.

# Defining Events

You can create events in ExpressWebJs via the Maker console command followed by your event name.

  ts-node maker make-events SalesOrder

This will create a SalesOrder_event.ts class in our App/Events directory.

"use strict";
import Emitter from "Elucidate/Emitter";

class SalesOrder {
  params: any;
  /**
   * Create a new event instance.
   * @param {*} params
   */
  constructor(params: any) {
    this.params = params;
    this.listenOn();
    Emitter.emitEvent("SalesOrder");
  }

  /**
   * Get the listener to listen to the event.
   */
  public async listenOn() {
    //
  }
}

export default SalesOrder;

# Defining Listeners

Next, lets's generate our salesOrder event listener with the following Maker command

   ts-node maker make-listener SalesOrderListener
"use strict";
import Emitter from "Elucidate/Emitter";

class SalesOrderListener {
  /**
   * Handle the event.
   * @param {*} eventName
   * @param {*} params
   */
  constructor(eventName: string, params: any) {
    Emitter.bind(eventName, () => {
      //Do something
    });
  }
}

export default SalesOrderListener;

Let's take a look at the SalesOrder event listener. Event listeners receive event instances in constructor. Within the constructor, you may perform any actions necessary to respond to the event.

# Binding Listeners To Events

Now that our SalesOrder event and listener is ready, we need to bind our SalesOrder listener to our SalesOrder event. We do that in our SalesOrder event in App/Events/SalesOrder_event.ts file:

"use strict";
import Emitter from "Elucidate/Emitter";
import SalesOrderListener from "App/Listeners/SalesOrder_listener";

class SalesOrder {
  params: any;
  /**
   * Create a new event instance.
   * @param {*} params
   */
  constructor(params: any) {
    this.params = params;
    this.listenOn();
    Emitter.emitEvent("SalesOrder");
  }

  /**
   * Get the listener to listen to the event.
   */
  public async listenOn() {
    new SalesOrderListener("SalesOrder", this.params);
  }

We can bind multiple listeners to an event. Let's say we have SlackNotification listener we want to add to SalesOrder event, we can do that by adding it in the listenOn method.

"use strict";
import Emitter from "Elucidate/Emitter";
import SalesOrderListener from "App/Listeners/SalesOrder_listener";
import SlackNotificationListener from "App/Listeners/SlackNotification_listener";

class SalesOrder {
  params: any;
  /**
   * Create a new event instance.
   * @param {*} params
   */
  constructor(params: any) {
    this.params = params;
    this.listenOn();
    Emitter.emitEvent("SalesOrder");
  }

  /**
   * Get the listener to listen to the event.
   */
  public async listenOn() {
    new SalesOrderListener("SalesOrder", this.params);
    new SlackNotificationListener("SalesOrder", this.params);
  }

# Using Events

Now that we have our event and listeners setup, let's use our event in maybe our Controller, Service or any where in our application.

import SalesOrder_event from "App/Events/SalesOrder_event";
import SalesModel from "App/Model/Sales_model";
import { Request, Response, NextFunction } from "Elucidate/HttpContext";
import HttpResponse from "Elucidate/HttpContext/ResponseType";

"use strict";
class SalesController {
  store = async (req: Request, res: Response, next: NextFunction) => {
    try {
      let savedSales = await SalesModel.query().insert(req.body);

      new SalesOrder_event(savedSales);

      return HttpResponse.OK(res, savedSales);
    } catch (error) {
      next(error);
    }
  };
}
export default SalesController;