# Events And Listeners

# Introduction

ExpressWebJs events provides a simple observer implementation, allowing you to subscribe and listen for events in your application. Event module can be imported and fired any where in your code, while their listeners are registered in the EventServiceProvider boot method. 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.

# Event Overview

Lets say we want to send a mail to our customers when ever they buy a product from us.

import { Event } from "Elucidate/Event";

export class SalesController extends BaseController {
  public async saveNewSales(req: Request, res: Response) {
    // save sales
    Event.fire("NewSales", { username: sales.username, email: sales.email });
  }
}

# Defining Listeners

You can create a function that sends mail to users once they buy our product.

export const SendMailToUser = async(username:string,email:string):Promise<void> =>{
  ...send email to user
}

# Binding Listener To Event

Now that our listener is ready, we need to bind our SendMailToUser listener to an event called NewSales. We do that in App/Providers/EventServiceProvider.ts file:

import ServiceProvider from "Elucidate/Support/ServiceProvider";
import { Event } from "Elucidate/Event";

export class EventServiceProvider extends ServiceProvider {
  /**
   * Register any other events for your application.
   * @return void
   */
  async boot(): Promise<void> {
    Event.bind("NewSales", SendMailToUser);
  }
}

# Binding Multiple Listeners To Event

We can bind multiple listeners to an event. Let's say we have SlackNotification listener we want to add to NewSales event, we can do that by binding it to NewSales event as an array.

import ServiceProvider from "Elucidate/Support/ServiceProvider";
import { Event } from "Elucidate/Event";

export class EventServiceProvider extends ServiceProvider {
  /**
   * Register any other events for your application.
   * @return void
   */
  async boot(): Promise<void> {
    Event.bind("NewSales", [SendMailToUser, SlackNotification]);
  }
}

# Using Events

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

import { Event } from "Elucidate/Event";
import SalesModel from "App/Model/SalesModel";
import { Request, Response } from "Config/Http";
import { BaseController } from "./BaseController";

export class SalesController extends BaseController {
  public async saveNewSales(req: Request, res: Response) {
    try {
      let sales = await SalesModel.query().insert(req.body);
      Event.fire("NewSales", { username: sales.username, email: sales.email });
      return this.response.OK(res, result);
    } catch (error) {
      return this.response.EXPECTATION_FAILED(res, error);
    }
  }
}