Using the Observer

The Observer class is a simple implementation of an observer pattern, which allows you to implement synchronous in-process events for a local service. It works full stack on every JavaScript system.

To use the Observer class, you will need to import it in your code:

import { Observer } from "./src/fi/hg/core/Observer";

You can then create an Observer instance by calling the constructor and passing in a name for the observer:

enum FooEvent {
    CHANGED = "FooService:changed",
}
const observer = new Observer<FooEvent>("MyObserver");

The Observer class provides several methods that you can use to listen for and trigger events:

listenEvent

The listenEvent method allows you to start listening for a specific event. It takes two arguments: the name of the event to listen for, and a callback function that will be called when the event is triggered. It returns a destructor function that you can use to stop listening for the event.

Here is an example of how to use the listenEvent method:

const destructor = observer.listenEvent('my-event', (eventName) => {
    console.log(`Event ${eventName} was triggered!`);
});

triggerEvent

The triggerEvent method allows you to trigger an event that you have previously registered to listen for using the listenEvent method. It takes one argument: the name of the event to trigger. Any additional arguments passed to the triggerEvent method will be passed on to the callback function when the event is triggered.

Here is an example of how to use the triggerEvent method:

observer.triggerEvent('my-event', 'some data');

waitForEvent

The waitForEvent method returns a Promise that is resolved when the specified event is triggered. It takes two arguments: the name of the event to wait for, and the maximum amount of time (in milliseconds) to wait for the event before timing out. If the event is not triggered within the specified timeout, the Promise is rejected with a timeout error.

Here is an example of how to use the waitForEvent method:

const eventPromise = observer.waitForEvent('my-event', 100);

destroy

The destroy method destroys the observer data and stops you from using the Observer instance. You should call the destroy method when you no longer need the Observer instance, to free up memory and prevent potential memory leaks.

Here is an example of how to use the destroy method:

observer.destroy();

Using the Observer with a service

To use the Observer class with a service, you can create a class that has an Observer instance as a static property. You can then create methods on the class that allow you to listen for and trigger events, as well as access any data that the service is managing.

Here is an example of how to use the Observer class with a service:

import Observer from "./src/fi/hg/core/Observer";

enum FooEvent {
    CHANGED = "FooService:changed",
}

class FooService {
    private static _data: any;

    private static _observer: Observer<FooEvent> = new Observer<FooEvent>("FooService");

    public static getData(): any {
        return this._data;
    }

    public static on(name: FooEvent, callback: ObserverCallback<FooEvent>): ObserverDestructor {
        return this._observer.listenEvent(name, callback);
    }

    public static refreshData() {
        HttpService.doSomething()
            .then((response) => {
                this._data = response.data;

                this._observer.triggerEvent(FooEvent.CHANGED);
            })
            .catch((err) => {
                console.error("Error: ", err);
            });
    }
}

FooService.on(FooEvent.CHANGED, () => {
    const currentData = FooService.getData();
    // ...
});

FooService.refreshData();

In this example, the FooService class has a static _observer property of type Observer<FooEvent>, which is initialized with the name "FooService". The class has a getData method that returns the current data managed by the service, and an on method that allows you to listen for events.

The refreshData method is used to update the data managed by the service and trigger the CHANGED event. To listen for the CHANGED event, you can call the on method and pass in a callback function. When the CHANGED event is triggered, the callback function will be called with the event name as its first argument.

You can then use the FooService class by calling the on method to listen for events and the refreshData method to trigger events and update the data.