Observer - JavaScript Design Patterns

İnanç Akduvan - Oct 26 '23 - - Dev Community

Hey hey my friends,
today, we will observe one of my favorite javascript patterns:

OBSERVER PATTERN

Sometimes, we need to have the same behaviour when different events occurred. If this is the case, Observer Pattern is a very useful guide for us.

Thanks to Observer Pattern, we can subscribe to objects, and observe changes in these objects.

Let's create a simple scenario and make some examples based on it.

Assume that:
Whenever a user log in or log out, we want to show an alert and also record this action into database. These two behaviours will be always the same for both log in and log out events.

1) We can achieve it by creating a class:
ObserveUserEvents class will have four parts:

  • observers: This is an array. It contains functions which will be triggered when a spesific event occured.
  • subscribe: This is a method to add functions which will be triggered into observers array.
  • unsubscribe: This is a method to remove functions from observers array. (just opposite of subscribe method.)
  • notify: This is a method to trigger all observers (functions added into observers array via subscribe method.)
class ObserveUserEvents {
    constructor() {
      this.observers = [];
    }

    subscribe(function) {
      this.observers.push(function);
    }

    unsubscribe(function) {
      this.observers = this.observers.filter((observer) => observer !== function);
    }

    notify(data) {
      this.observers.forEach((observer) => observer(data));
    }
}
Enter fullscreen mode Exit fullscreen mode

OK, ready! Now we need two functions. One for showing alert. One for recording data into database.

Surely, I will not create real functions for these actions. We will create some placeholder functions just for now and assume that they are real 🤡

2) Time to create our functions:

function recordToDatabase(data) {
    console.log({
       recordTitle: data,
       recordDate: Date.now()
    });
}

function showAlert(data) {
    console.log("Alert message:", data);
}
Enter fullscreen mode Exit fullscreen mode

Good, good, good. Now, We would like to trigger these two functions named recordToDatabase and showAlert whenever a user log in or log out. Then, the only thing we need to do here is to subscribe them.

3) Let's subscribe:

const observable = new ObserveUserEvents();

observable.subscribe(recordToDatabase);
observable.subscribe(showAlert);
Enter fullscreen mode Exit fullscreen mode

Subscribed! 📪 From now on, whenever we notify observers, these functions will be triggered. Awesome!

It is better to continue with our scenario.
So assume that, we have two buttons. One for log in event, one for log out event. So let's assign click events to them and notify observers on their click.

4) Notify observers:

const loginButton = document.getElementById("loginButton");
const logoutButton = document.getElementById("logoutButton");

loginButton.addEventListener("click", () => {
  observable.notify("User logged in");

  // In background, it actually runs:
  // recordToDatabase("User logged in");
  // showAlert("User logged in");
  // So if you check console, you will see it prints:
  // {
  //   recordTitle: "User logged in",
  //   recordDate: Date.now()
  // }
  // and also it prints:
  // "Alert message: User logged in"
});

logoutButton.addEventListener("click", () => {
  observable.notify("User logged out");

  // In background, it actually runs:
  // recordToDatabase("User logged out");
  // showAlert("User logged out");
  // So if you check console, you will see it prints:
  // {
  //   recordTitle: "User logged out",
  //   recordDate: Date.now()
  // }
  // and also it prints:
  // "Alert message: User logged out"
});
Enter fullscreen mode Exit fullscreen mode

ta-taam 👻 now, you can notify and trigger the same behaviour only with one line code and anywere you want.

This was a just small example, my friends, to explain the logic. We can take this pattern as a guide and customize it to our specific needs.


I am glad that you read it until here.
Please, don't hesitate to give feedback, contribute, contact and correct me. Also, please, comment, like and share 🥺


Follow me on:

Github: https://github.com/inancakduvan/
Twitter: https://twitter.com/InancAkduvan

Thank you for coming with me until end of the reading! 🙂

. . . . . . . . . . . .