Gathering adorned categorizations (sans any listed category divisions)

My current setup involves an event dispatcher class that triggers listeners on specified occurrences. I've successfully implemented registering event listeners via decorators, but I feel like there may be a better solution out there.

At the moment, event listeners are gathered in a global registry and then registered with the event dispatcher. Simplified, my decorator looks like this:

// Decorator
export const EventListener = (events: string[]) => {
  return (target: Type<object>): void => {
    EventListenerRegistry.set(target);
  };
};

// Listener example
@EventListener(['start'])
class OnStart {
  public handle() {
  }
}

With this setup, the OnStart listener is activated when the start event occurs.

One aspect of this approach that bothers me is the requirement for the EventListenerRegistry, which appears as follows:

export const EventListenerRegistry = (new class {
    protected listeners = [];

    public set(target) {
        this.listeners.push(target);
    }
});

Using the EventListenerRegistry means importing the same instance throughout, giving it somewhat of a "singleton" behavior.

Since my listeners are loaded with require via glob, the current setup automatically registers them with the dispatcher without extra effort on my part.

Despite this convenience, I wonder if there's a cleaner alternative to using registry classes. Any suggestions?

Answer №1

If I were to implement IoC in TypeScript, one option would be using a tool like Inversify. Here is an example of how it could be utilized:

import { injectable, inject } from 'inversify';

enum EventType {
  Start,
}

interface IEvent {
  type: Event;
  handle(): void;
}

@injectable()
class OnStart implements IEvent {
  public readonly type = EventType.Start;
  public handle() {
  }
}

@injectable()
class Application {
  public constructor(@multiInject(EVENT) public events: IEvent[]) {
  }
}

However, manual binding is required for this approach:

export const EVENT = symbol('event');
container.bind<IEvent>(EVENT).to(OnStart);
...

Alternatively, if you prefer automatic registration of events, you could possibly import the container into your decorators and perform the binding there.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Display a semantic-ui-react popup in React utilizing Typescript, without the need for a button or anchor tag to trigger it

Is there a way to trigger a popup that displays "No Data Found" if the backend API returns no data? I've been trying to implement this feature without success. Any assistance would be greatly appreciated. I'm currently making a fetch call to retr ...

Angular is not rendering styles correctly

Having two DOMs as depicted in the figures, I'm facing an issue where the circled <div class=panel-heading largeText"> in the first template receives a style of [_ngcontent-c1], while that same <div> gets the style of panel-primary > .p ...

Adjusting the array when items in the multi-select dropdown are changed (selected or unselected)

I am looking to create a multi-select dropdown in Angular where the selected values are displayed as chip tags. Users should be able to unselect a value by clicking on the 'X' sign next to the chip tag, removing it from the selection. <searcha ...

Tips for iterating through an observable using the .subscribe method

I am currently working on a function that involves looping and using .subscribe to receive an array object each time, with the intention of later pushing this data into another array. The loop itself is functional; however, there is an issue with the resul ...

Using the useRef hook in a TypeScript project to retrieve a boolean value

As I work on developing an application using Nextjs, I have encountered an issue while using react useRef with typescript. The problem arises when I use useRef without typescript, everything works smoothly. However, the moment I include HTMLDivEleement as ...

Is there a way to simultaneously filter by two attributes using mat-select-filter in Angular?

I have integrated the mat-select-filter library in my Angular project, but I am facing an issue with the displayMember filter. Currently, it only filters by code, but I would like it to also filter by name simultaneously. Is there a way to achieve this u ...

Leveraging Fastify's preHandler middleware functionality

Implementing a middleware to validate user authentication before accessing the specified route. Encountering an issue where tokenService inside tokenController is showing as undefined when passing tokenController.authUser as a middleware. However, the met ...

Struggling with the error message "Type 'ChangeEvent<unknown>' is not assignable to type 'ChangeEvent<MouseEvent>'" while working with React and TypeScript? Here's how you can tackle this issue

Within the App.tsx file, I encountered an issue with the Material UI Pagination component where it was throwing an error related to type mismatch. The error message stated: Argument of type 'ChangeEvent' is not assignable to parameter of type &ap ...

Setting a blank value or null equivalent to a field: Tips and tricks

Here is the component state that I am working with: interface Person { name: string; surname: string; } interface CompState{ //...fields ... person?: Person; } render() { if(this.state.person){ const comp = <div>{this. ...

Ensuring Type Safety in Typescript

I have a specific requirement where I need to validate the structure of a request body to ensure it conforms to a predefined type. Is there a way or a package that can help achieve this validation? type SampleRequestBody = { id: string; name: string; ...

Displayed even when data is present, the PrimeNg empty message persists

I have set up a PrimeNg table to display data with an empty message template like this: <ng-template pTemplate="emptymessage"> <tr> <td> No records found </td> </tr> </ng-template> ...

Next.js page freezes when Axios request is made causing the tab to become unresponsive

Curious about how to troubleshoot (or where to start) with my current Axios problem. I am working on a Next.js project (12.3) and have an axios interceptor hook that manages all of my internal requests. The interceptor functions properly on every action/pa ...

Encountering a Angular 12 Observable<Object[]> Error while attempting to execute a GET request

I've been grappling with this error I encountered while working on Angular 12. Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays. This is the code f ...

JavaScript method of retrieving an object inside an array nested within another object via multer

Below is my custom multer function to handle file uploads - const storage = multer.diskStorage({ destination: (req, file, callback) => { let type = req.params.type; let path = `./data/${type}`; fs.mkdirsSync(path); callback(null, path) ...

Angular : How can a single item be transferred from an array list to another service using Angular services?

How to Transfer a Single List Item to the Cart? I'm working on an Angular web application and I need help with transferring a single item from one service to another service and also displaying it in a different component. While I have successfully i ...

The type 'TaskListProps[]' cannot be assigned to type 'TaskListProps'

I'm struggling with handling types in my TypeScript application, especially with the TaskListProps interface. export default interface TaskListProps { tasks: [ { list_id: string; title: string; description: string; status ...

Connect the names of the sheets with the data in the tables

I have a simple question: I want to connect specific sheet names in my workbook with a table that contains a range of dates. The sheet names should be something like "blablabla" + Table@1. Although I have attempted to design a solution, it doesn't se ...

Tips for resolving this unhandled error in React TypeScript

After creating a program in React TypeScript, I encountered an uncaught error. Despite running and debugging tests and conducting extensive research on Google, I have been unable to resolve this issue on my own. Therefore, I am reaching out for assistance ...

Providing a conditional getServerSideProps function

Is there a way to dynamically activate or deactivate the getServerSideProps function using an environment variable? I attempted the following approach: if (process.env.NEXT_PUBLIC_ONOFF === 'true') { export const getServerSideProps: Get ...

Utilize Firebase for Playwright to efficiently implement 'State Reuse' and 'Authentication Reuse'

In my testing environment, I want to eliminate the need for repeated login actions in each test run. My approach involves implementing 'Re-use state' and 'Re-use Authentication', but I've encountered a challenge with Firebase using ...