Events
The Geins SDK provides a robust event management system that allows you to handle and respond to various events within your application seamlessly. This system is essential for building responsive and interactive applications, enabling real-time updates and efficient communication between different parts of your app.
This article will guide you through the events module in GeinsCore
, including how to listen for events, emit events, and manage event messages and types. We'll also provide practical examples, including TypeScript methods, to illustrate how to integrate event handling into your application effectively.
Usage
The SDK emits events to notify your application of important changes or actions. You can listen for these events and respond accordingly. Events are useful for updating the user experience across browser tabs, integrating third-party services, tracking user actions, and more.
Events serve as a communication bridge within your application, allowing different components to react to specific actions without being tightly coupled.
Overview
The GeinsCore
class provides methods to manage events. You can listen for specific events, broadcast events, and access event data.
EventService
: Manages event listeners and emits events.GeinsEventMessage
: Defines the structure of event messages.GeinsEventType
: Enumerates the types of events that can be emitted and listened to.
By leveraging the events system, you can create a dynamic and responsive application that reacts to user interactions, data changes, and other significant occurrences.
Event Message Structure
The GeinsEventMessage
interface defines the structure of the messages associated with events. It ensures consistency and type safety when handling event data.
/**
* Event message interface
* @interface
* @name GeinsEventMessage
* @property {string} subject - Event subject
* @property {any} payload - Event payload
* @property {boolean} [broadcast] - Broadcast event over windows and tabs
* @example
* {
* subject: 'USER_LOGIN',
* payload: {
* user: 'luke.skywalker@tatooine.com',
* },
* broadcast: true,
* }
*/
export interface GeinsEventMessage {
subject: string;
payload: any;
broadcast?: boolean;
}
The subject
provides context about the event, while the payload
carries the actual data related to the event. The optional broadcast
property indicates whether the event should be broadcasted across different contexts (e.g., browser tabs).
Emitting an Event
To emit an event, use the push
method provided by the EventService
. This method allows you to send event messages that other parts of your application can listen for and respond to.
import { GeinsCore, GeinsEventType } from '@geins/core';
import type { GeinsSettings, GeinsEventMessage } from '@geins/types';
const geinsSettings: GeinsSettings = {
apiKey: 'your-api-key',
accountName: 'your-account-name',
channel: 'your-channel-id',
tld: 'your-tld',
locale: 'your-locale',
market: 'your-market',
};
const geinsCore = new GeinsCore(geinsSettings);
// Emitting a simple toast event
geinsCore.events.push({ subject: 'toast', payload: 'Hello world' });
// Emitting an auth event
geinsCore.events.push({ subject: 'auth', payload: { method: 'login' } });
// Emitting a user login event with a specific event type
const message: GeinsEventMessage = {
subject: 'user.auth',
payload: { method: 'login yes' },
};
geinsCore.events.push(message, GeinsEventType.USER_LOGIN);
In this example:
- A simple toast event is emitted with a message payload.
- An auth event is emitted with a payload containing the login method.
- A user login event is emitted with a specific event type and a more detailed payload.
Broadcasts of Events
Events can be broadcasted across different browser contexts (e.g., multiple tabs) using the BroadcastChannel
API. This ensures that events are propagated throughout the entire application, regardless of the context in which they occur.
When emitting an event with the broadcast
property set to true
(or omitted, as it defaults to true
), the event will be sent to all listeners across different contexts.
const eventMessage: GeinsEventMessage = {
subject: 'user.auth',
payload: { method: 'login yes' },
broadcast: true, // This event will be broadcasted
};
geinsCore.events.push(eventMessage, GeinsEventType.USER_LOGIN);
In this example, the USER_LOGIN
event is broadcasted, ensuring that all parts of the application, including other browser tabs, receive and can respond to the event.
Listening for Events
To respond to events emitted by the SDK, you need to add event listeners. The EventService
provides methods to add listeners that can handle events when they occur.
Adding Event Listeners
geinsCore.events.listenerAdd(handler: (data: GeinsEventMessage) => void, eventName?: GeinsEventType | string);
geinsCore.events.listenerOnce(handler: (data: GeinsEventMessage) => void, eventName?: GeinsEventType | string);
- listenerAdd
: Adds a persistent event listener for the specified event.
- listenerOnce
: Adds a one-time event listener that is removed after it is triggered once.
Removing Event Listeners
geinsCore.events.listenerRemove(eventName?: GeinsEventType | string);
geinsCore.events.listenerRemoveAll(eventName?: GeinsEventType | string);
- listenerRemove
: Removes all listeners for the specified event.
- listenerRemoveAll
: Removes all listeners for the specified event.
Counting and Retrieving Listeners
geinsCore.events.listenerCount(eventName?: GeinsEventType | string);
geinsCore.events.listenersGet(eventName?: GeinsEventType | string);
- listenerCount
: Returns the number of listeners for the specified event.
- listenersGet
: Retrieves all listeners for the specified event.
Managing Event Listeners
Managing event listeners effectively is crucial for ensuring that your application responds appropriately to events without causing memory leaks or unintended behavior. The EventService
class provides a set of methods to add, remove, count, and retrieve event listeners.
EventService Class Methods
The EventService
class includes the following methods to manage event listeners:
listenerAdd
Adds a persistent event listener for the specified event. This listener will be invoked every time the event is emitted.
listenerAdd(handler: (data: GeinsEventMessage) => void, eventName?: GeinsEventType | string);
Parameters:
handler
: A callback function that handles the event data.eventName
(optional): The name of the event to listen for. If omitted, it defaults to'geins-event'
.
Example:
geinsCore.events.listenerAdd((data: GeinsEventMessage) => {
console.log('Received event:', data.subject, data.payload);
}, GeinsEventType.USER_LOGIN);
listenerOnce
Adds a one-time event listener for the specified event. This listener will be invoked only the first time the event is emitted and then automatically removed.
listenerOnce(handler: (data: GeinsEventMessage) => void, eventName?: GeinsEventType | string);
Parameters:
handler
: A callback function that handles the event data.eventName
(optional): The name of the event to listen for. If omitted, it defaults to'geins-event'
.
Example:
geinsCore.events.listenerOnce((data: GeinsEventMessage) => {
console.log('This will log only once:', data.subject, data.payload);
}, GeinsEventType.USER_LOGOUT);
listenerRemove
Removes all listeners for the specified event.
listenerRemove(eventName?: GeinsEventType | string);
Parameters:
eventName
(optional): The name of the event for which to remove listeners. If omitted, it defaults to'geins-event'
.
Example:
geinsCore.events.listenerRemove(GeinsEventType.CART_ADD);
listenerRemoveAll
Removes all listeners for the specified event. This is functionally identical to listenerRemove
.
listenerRemoveAll(eventName?: GeinsEventType | string);
Parameters:
eventName
(optional): The name of the event for which to remove all listeners. If omitted, it defaults to'geins-event'
.
Example:
geinsCore.events.listenerRemoveAll(GeinsEventType.CART_REMOVE);
listenerCount
Returns the number of listeners currently registered for the specified event.
listenerCount(eventName?: GeinsEventType | string): number;
Parameters:
eventName
(optional): The name of the event for which to count listeners. If omitted, it defaults to'geins-event'
.
Returns: number
– The count of listeners for the specified event.
Example:
const loginListenerCount = geinsCore.events.listenerCount(
GeinsEventType.USER_LOGIN,
);
console.log('Number of USER_LOGIN listeners:', loginListenerCount);
listenersGet
Retrieves all listeners for the specified event.
listenersGet(eventName?: GeinsEventType | string): Function[];
Parameters:
eventName
(optional): The name of the event for which to retrieve listeners. If omitted, it defaults to'geins-event'
.
Returns: Function[]
– An array of listener functions for the specified event.
Example:
const cartAddListeners = geinsCore.events.listenersGet(GeinsEventType.CART_ADD);
cartAddListeners.forEach((listener, index) => {
console.log(`Listener ${index + 1}:`, listener);
});
push
Emits an event with the given message and event name. This method not only triggers the event listeners but also handles broadcasting the event across different contexts if the broadcast
property is set to true
.
push(eventMessage: GeinsEventMessage, eventName?: GeinsEventType | string);
Parameters:
eventMessage
: An object adhering to theGeinsEventMessage
interface, containing the event's subject and payload.eventName
(optional): The name of the event to emit. If omitted, it defaults to'geins-event'
.
Example:
const eventMessage: GeinsEventMessage = {
subject: 'user.auth',
payload: {
userId: 'user-123',
timestamp: new Date(),
},
broadcast: true, // This event will be broadcasted
};
geinsCore.events.push(eventMessage, GeinsEventType.USER_LOGIN);
This will emit the USER_LOGIN
event with the provided message, and since broadcast
is set to true
, the event will be sent to all listeners across different browser contexts.
Events Always Emitted by the SDK
The SDK emits a set of predefined events that you can listen to for handling user actions and cart operations. These events are categorized under user and cart-related actions.
GeinsEventType
Enum
// enum over event types to subscribe to
export enum GeinsEventType {
// User
USER = 'USER',
USER_LOGIN = 'USER_LOGIN',
USER_LOGOUT = 'USER_LOGOUT',
USER_UPDATE = 'USER_UPDATE',
USER_DELETE = 'USER_DELETE',
// Cart
CART = 'CART',
CART_ADD = 'CART_ADD',
CART_REMOVE = 'CART_REMOVE',
CART_UPDATE = 'CART_UPDATE',
CART_CLEAR = 'CART_CLEAR',
}
These event types can be used to listen for and respond to specific actions within your application.
- USER_LOGIN: Triggered when a user logs in.
- USER_LOGOUT: Triggered when a user logs out.
- CART_ADD: Triggered when an item is added to the cart.
- CART_REMOVE: Triggered when an item is removed from the cart.
Example: Sending Data to a Third-Party Service on User Login
Let's create an example where we send user login data to a third-party analytics service whenever a user logs in. We'll listen for the USER_LOGIN
event and trigger an API call to the analytics service.
import { GeinsCore, GeinsEventType } from '@geins/core';
import type { GeinsSettings, GeinsEventMessage } from '@geins/types';
import axios from 'axios';
const geinsSettings: GeinsSettings = {
apiKey: 'your-api-key',
accountName: 'your-account-name',
channel: 'your-channel-id',
tld: 'your-tld',
locale: 'your-locale',
market: 'your-market',
};
const geinsCore = new GeinsCore(geinsSettings);
// Define an event handler for USER_LOGIN
const handleUserLogin = async (eventMessage: GeinsEventMessage) => {
const userData = eventMessage.payload;
try {
await axios.post('https://third-party-analytics.com/login', {
userId: userData.userId,
timestamp: userData.timestamp,
});
console.log('User login data sent to analytics service.');
} catch (error) {
console.error('Failed to send user login data:', error);
}
};
// Add the event listener
geinsCore.events.listenerAdd(handleUserLogin, GeinsEventType.USER_LOGIN);
// Emit a USER_LOGIN event (this would typically be triggered elsewhere in your application)
const loginEventMessage: GeinsEventMessage = {
subject: 'user.auth',
payload: {
userId: 'user-123',
timestamp: new Date(),
},
broadcast: true,
};
geinsCore.events.push(loginEventMessage, GeinsEventType.USER_LOGIN);
In this example:
- We initialize
GeinsCore
with the necessary settings. - We define an event handler
handleUserLogin
that sends user login data to a third-party analytics service usingaxios
. - We add the event listener for the
USER_LOGIN
event. - We emit a
USER_LOGIN
event with relevant user data.
This setup ensures that every time a user logs in, their login information is sent to the analytics service, allowing you to track user activities effectively.
Example: TypeScript Methods
Below are examples of how to use the EventService
methods within your TypeScript code.
Adding a Persistent Event Listener
geinsCore.events.listenerAdd((data: GeinsEventMessage) => {
console.log('Received event:', data.subject, data.payload);
}, GeinsEventType.USER_LOGIN);
This listener will log the event data every time a USER_LOGIN
event is emitted.
Adding a One-Time Event Listener
geinsCore.events.listenerOnce((data: GeinsEventMessage) => {
console.log('This will log only once:', data.subject, data.payload);
}, GeinsEventType.USER_LOGOUT);
This listener will log the event data only the first time a USER_LOGOUT
event is emitted and then remove itself.
Removing Event Listeners
geinsCore.events.listenerRemove(GeinsEventType.CART_ADD);
Removes all listeners associated with the CART_ADD
event.
Removing All Event Listeners
geinsCore.events.listenerRemoveAll(GeinsEventType.CART_REMOVE);
Removes all listeners associated with the CART_REMOVE
event.
Counting Event Listeners
const loginListenerCount = geinsCore.events.listenerCount(
GeinsEventType.USER_LOGIN,
);
console.log('Number of USER_LOGIN listeners:', loginListenerCount);
Logs the number of listeners currently registered for the USER_LOGIN
event.
Retrieving Event Listeners
const cartAddListeners = geinsCore.events.listenersGet(GeinsEventType.CART_ADD);
cartAddListeners.forEach((listener, index) => {
console.log(`Listener ${index + 1}:`, listener);
});
Retrieves and logs all listeners registered for the CART_ADD
event.
Emitting an Event
const eventMessage: GeinsEventMessage = {
subject: 'user.auth',
payload: {
userId: 'user-123',
timestamp: new Date(),
},
broadcast: true, // This event will be broadcasted
};
geinsCore.events.push(eventMessage, GeinsEventType.USER_LOGIN);
Emits a USER_LOGIN
event with the specified message, broadcasting it across all contexts.
Example: TypeScript Methods
Below are examples of how to use the EventService
methods within your TypeScript code.
Adding a Persistent Event Listener
geinsCore.events.listenerAdd((data: GeinsEventMessage) => {
console.log('Received event:', data.subject, data.payload);
}, GeinsEventType.USER_LOGIN);
This listener will log the event data every time a USER_LOGIN
event is emitted.
Adding a One-Time Event Listener
geinsCore.events.listenerOnce((data: GeinsEventMessage) => {
console.log('This will log only once:', data.subject, data.payload);
}, GeinsEventType.USER_LOGOUT);
This listener will log the event data only the first time a USER_LOGOUT
event is emitted and then remove itself.
Removing Event Listeners
geinsCore.events.listenerRemove(GeinsEventType.CART_ADD);
Removes all listeners associated with the CART_ADD
event.
Counting Event Listeners
const loginListenerCount = geinsCore.events.listenerCount(
GeinsEventType.USER_LOGIN,
);
console.log('Number of USER_LOGIN listeners:', loginListenerCount);
Logs the number of listeners currently registered for the USER_LOGIN
event.
Retrieving Event Listeners
const cartAddListeners = geinsCore.events.listenersGet(GeinsEventType.CART_ADD);
cartAddListeners.forEach((listener, index) => {
console.log(`Listener ${index + 1}:`, listener);
});
Retrieves and logs all listeners registered for the CART_ADD
event.
Emitting an Event
const eventMessage: GeinsEventMessage = {
subject: 'user.auth',
payload: {
userId: 'user-123',
timestamp: new Date(),
},
broadcast: true, // This event will be broadcasted
};
geinsCore.events.push(eventMessage, GeinsEventType.USER_LOGIN);
Emits a USER_LOGIN
event with the specified message, broadcasting it across all contexts.