Use observables to notify subscribers when an event occurs.
With the observer pattern, we have:
1. An **observable object**, which can be observed by subscribers in order to notify them.
2. **Subscribers**, which can subscribe to and get notified by the observable object.
For example, we can add the `logger` as a subscriber to the observable.
<video src="https://res.cloudinary.com/dq8xfyhu4/video/upload/q_auto/v1661499081/FM%20Workshop/design-patterns/observable-pattern/observable2_nsxqmi.mov" controls="controls" style="width: 100%;"></video>
When the `notify` method is invoked on the observable, all subscribers get invoked and (optionally) pass the data from the notifier to them.
<video src="https://res.cloudinary.com/dq8xfyhu4/video/upload/q_auto/v1661499025/FM%20Workshop/design-patterns/observable-pattern/observable_dtcqep.mov" controls="controls" style="width: 100%;"></video>
## How to Create an Observer?
We can export a singleton Observer object, which contains a `notify`, `subscribe`, and `unsubscribe` method.
```ts
const observers = [];
export default Object.freeze({
notify: (data) => observers.forEach((observer) => observer(data)),
subscribe: (func) => observers.push(func),
unsubscribe: (func) => {
[...observers].forEach((observer, index) => {
if (observer === func) {
observers.splice(index, 1);
}
});
},
});
```
We can use this observable throughout the entire application, making it possible to subscribe functions to the observable
```ts
import Observable from "./observable";
function logger(data) {
console.log(`${Date.now()} ${data}`);
}
Observable.subscribe(logger);
```
and notify all subscribers based on certain events.
```ts
import Observable from "./observable";
document.getElementById("my-button").addEventListener("click", () => {
Observable.notify("Clicked!"); // Notifies all subscribed observers
});
```