# Events

There will come a time in your real world application where you would want to run some actions before or after something happens. e.g Send otp codes, Do something after a post has been deleted.
With xpresser events, you can listen to events called anywhere in your application.

# Generate an Events file.

An events file is where multiple related events can be defined. You can think of it like the controller for event handling.

To generate an event file, use the xjs-cli make:event

xjs make:event <EventName>

# example
xjs make:event UserEvents
# Creates a file @ backend/events/UserEvents.(js|ts)

Note: xjs-cli does not automatically add the keyword Events to the name you provide if it does not exist like in controllers or middlewares.

# Usage

Using the UserEvents class below

# Emitting Events

# $.events.emit(event: string, ...args: any[])

The above events can be called like so:

$.events.emit("UserEvents"); // Calls `index` method
$.events.emit("UserEvents.onLogin");
$.events.emit("UserEvents.onSignup");
$.events.emit("UserEvents.onFullNameChange", user);

The index method is called by default. it also inherits namespace as name. Using the example above, the index method will run when we call $.events.emit("UserEvents")

# Emit after a specific time.

# $.events.emitAfter(ms: number, event: string, ...args: any[])

By default, all events run in background immediately and not waited for. You can also decide when to start an event.

$.events.emitAfter(3000, "someEvent") // starts after 3 seconds

Note: Durations are in milliseconds

# Emit with a Callback

If you want to run a function after an event has completed, you can use the $.events.emitWithCallback(event, arguments, callback) method.

$.events.define('someEvent', () => "DONE!");

$.events.emitWithCallback('someEvent', [arguments], (returned) => {
  // returned === "DONE!"
})

# Emit from Controller Actions

There is no difference when using events in controllers, once you have your xpresser instance you can call events.

const $ = require("xpressser").getInstance();

const AccountController = {
  
  updateProfile(http, {user}) {
    // If instance ($) is available already
    $.events.emit("UserEvents.onFullNameChange", user)
    
    // OR instance from http.$(?)
    http.$("events").emit("UserEvents.onFullNameChange", user)
    
    // OR instance from http.$instance()
    http.$instance().events.emit("UserEvents.onFullNameChange", user)
  }
}