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 }); ```