Skip to content

The Observer Pattern in JavaScript explained

The Observer Pattern is a popular pattern used across all sorts of JavaScript applications. The instance (subject) maintains a collection of objects (observers) and notifies them all when changes to the state occurs. Does that sound difficult to you? Yes, it was upsetting me as well when I came across this pattern for a first time. A tiny practical example may help you to grasp the concept.

Imagine that you have to update multiple elements simultaneously when some event occurs (typing inside the input field perhaps). You need to be able to add more (subscribe) elements that react (observe) to a change of an input value. Removing subscriptions (unsubscribe) can be handy if you no longer need to broadcast state changes to a particular object. Do you get the idea now? Let’s code it!

// define a class
class Observable {
  // each instance of the Observer class
  // starts with an empty array of things (observers)
  // that react to a state change
  constructor() {
    this.observers = [];
  }

  // add the ability to subscribe to a new object / DOM element
  // essentially, add something to the observers array
  subscribe(f) {
    this.observers.push(f);
  }

  // add the ability to unsubscribe from a particular object
  // essentially, remove something from the observers array
  unsubscribe(f) {
    this.observers = this.observers.filter(subscriber => subscriber !== f);
  }

  // update all subscribed objects / DOM elements
  // and pass some data to each of them
  notify(data) {
    this.observers.forEach(observer => observer(data));
  }
}

The use-case example goes like this…

// some DOM references
const input = document.querySelector('.js-input');
const p1 = document.querySelector('.js-p1');
const p2 = document.querySelector('.js-p2');
const p3 = document.querySelector('.js-p3');

// some actions to add to the observers array
const updateP1 = text => p1.textContent = text;
const updateP2 = text => p2.textContent = text;
const updateP3 = text => p3.textContent = text;

// instantiate new Observer class
const headingsObserver = new Observable();

// subscribe to some observers
headingsObserver.subscribe(updateP1);
headingsObserver.subscribe(updateP2);
headingsObserver.subscribe(updateP3);

// notify all observers about new data on event
input.addEventListener('keyup', e => {
  headingsObserver.notify(e.target.value);
});

With a little help of a few control buttons (added to make the demo more interactive), it gives you the power to do cool things like this with just a few lines of code. Isn’t it nice?

See the Pen XaVRyY by Pawel Grzybek (@pawelgrzybek) on CodePen.

This very simplified version of the observer pattern can save you from downloading some costly frameworks like Vue or React. If you are looking for a detailed explanation of it, I can’t recommend enough “Learning JavaScript Design Patterns” by Addy Osmani. Classic! Sometimes “Publication / Subscription” is used interchangeably to describe this pattern, although there are some minor differences between them and Addy points them all out in his book. Hopefully this article helped you out. Until next time curious people :-)

Comments

  • t
    thommorais

    <3

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • M
    Matt Savino

    Any hints for debugging Observable? I've found that challenging in complex apps.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • P
      Piotr Kowalski

      Try that tool: https://cartant.github.io/r...

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • v
    vladyn

    I would like to say - very, very useful overview. Thanks!

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thanks a lot for your kind words! Stay tuned! More to come :)

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • A
    Andrea Falzetti

    Interesting pattern and well explained. Thanks for sharing!

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Glad you like it! Have a lovely day 🥑

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • V
    Vitimus

    This is basically the same as a event bus

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Never heard of it. Promise to catch up :)

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • S
    ShirtlessKirk

    Welcome to knockout.js...

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • Ł
    Łukasz Pilarski

    Nice post. It inspired me to experiment with more functional solution. The result:
    https://jsfiddle.net/oshj2a...

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thanks a ton for positive feedback. I'g glad my explanation inspired you to make a cool stuff!

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
      • V
        Vaas

        'more fonctionnal solution' say web dev: i only see defactorization

        👆 you can use Markdown here

        Your comment is awaiting moderation. Thanks!
        • Ł
          Łukasz Pilarski

          You learn something new every day. Thanks.

          👆 you can use Markdown here

          Your comment is awaiting moderation. Thanks!
          • d
            disqus_mqsWS8YsX9

            ukaszpilarski more

            👆 you can use Markdown here

            Your comment is awaiting moderation. Thanks!
  • Q
    Quốc Hưng Lê

    Nice post! I think this's the best explain-it-like-i-am-5 article on Observer pattern that I've come across. Simple and concise. Thanks!

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thanks!Stay tuned because I'm going to explain more patterns in future posts 🍿

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • P
    Pat

    Great explanation. Thank you 👌

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • J
    Jarod

    Nice Post. Best and Simplest explanation of observer pattern. Thank you

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • R
    Russell Dow

    Thanks for the concise example. I implemented this pattern during a React tutorial and needed to see it in a more simplified environment to understand the pertinent parts.

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Hi. Thanks for kind words. Two directional binding in React is super easy to do. This pattern in frameworks like React or Vue is a little bit useless I think.

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • W
    Will Hoskings

    Love ya :) Totally get it now

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      I am glad you found it helpful. Enjoy your day :)

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • N
    Nuri Yilmaz

    :) i like it specialy this part "observer pattern can save you from downloading some costly frameworks like Vue or React". how about whole implemented libraries? Microsoft produced XAML many many years ago and people speak about "observable" on 2017. its too late.
    And what you think about RxJS library?

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • T
    Tristan Forward

    Your codepen example says "Subscrube" instead of "Subscribe".

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thanks a lot Tristan. All fixed :-)

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • E
    Ezequiel Regaldo

    Finally a good guide with class ! :D thank you so much

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      My pleasure!

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • Y
    Yogesh Sharma

    Nice post

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thanks a ton. Have a great day!

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!
  • C
    Celso Alves Guarani Kaiowá

    I creted this repo https://github.com/lcelso/d...

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
  • Y
    Yogesh Bhat

    Great content and very practical. Thank you

    👆 you can use Markdown here

    Your comment is awaiting moderation. Thanks!
    • Pawel Grzybek
      Pawel Grzybek

      Thanks a ton @disqus_Wmudoiw1Jj:disqus. Have a nice day!

      👆 you can use Markdown here

      Your comment is awaiting moderation. Thanks!

What'ya think?

👆 you can use Markdown here

Your comment is awaiting moderation. Thanks!