Search code examples
javascriptglobaldispatch

Custom global javascript event dispatcher


I am trying to create a custom event dispatcher. I have read this article and implemented the code

export default class Dispatcher{
    constructor(){

    }

    addListener (event, callback) {
        // Check if the callback is not a function
        if (typeof callback !== 'function') {
            console.error(`The listener callback must be a function, the given type is ${typeof callback}`);
            return false;
        }
        // Check if the event is not a string
        if (typeof event !== 'string') {
            console.error(`The event name must be a string, the given type is ${typeof event}`);
            return false;
        }
            
        // Create the event if not exists
        if (this.events[event] === undefined) {
            this.events[event] = {
                listeners: []
            }
        }
            
        this.events[event].listeners.push(callback);
    }

    removeListener(event, callback){
        //check if this event not exists
        if(this.events[event] === undefined){
            console.error(`This event: ${event} does not exist`);
            return false;
        }

        this.events[event].listeners = this.events[event].listeners.filter(listener => {
            return listener.toString() !== callback.toString();
        })
    }

    dispatch(event, details){
        //check if this event not exists
        if(this.events[event] === undefined){
            console.error(`This event: ${event} does not exist`);
            return false;
        }

        this.events[event].listeners.forEach((listener) => {
            listener(details);
        })
    }
}

my goal is for my external classes that I import into my main JavaScript file to be able to dispatch events globaly. so i want my js imported like this

import {API2} from '/js/API2.js'

to be able to dispatch an event that can be captured from the main.js file that originally imports the API2 class.

one way that I have tried is to attach the imported dispatcher class to window but this is obviously wrong and produces no result.

How could one implement a dispatcher class that allows me to add events and dispatch events globally from anywhere in the code imported or not?


Solution

  • If I understand it correctly, you want 2 things:

    1. Import the dispatcher into a file and use the class directly
    2. Use a global object to interact with the class

    1. import into a file and use it directly

    In order to import it directly and use it, create a singleton (so 1 instance of the class) and export it directly:

    class Dispatcher{
       ...
    }
    
    export default new Dispatcher() // this will initialise the singleton instantly
    

    In order to use it, you can now import it in any file:

     import dispatcher from './dispatcher.js';
    

    It will be the same instance anywhere.

    2. make it global

    In order to make it global you could actually update the file with the following (either global for nodejs or window for web):

    class Dispatcher{
       ...
    }
    
    const dispatcherSingleton = new Dispatcher();
    
    window.dispatcherSingleton = dispatcherSingleton // web
    global.dispatcherSingleton = dispatcherSingleton // nodejs
    
    export default dispatcherSingleton // export the singleton