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 :-)
<3
Any hints for debugging Observable? I've found that challenging in complex apps.
Try that tool: https://cartant.github.io/r...
I would like to say - very, very useful overview. Thanks!
Thanks a lot for your kind words! Stay tuned! More to come :)
Interesting pattern and well explained. Thanks for sharing!
Glad you like it! Have a lovely day 🥑
This is basically the same as a event bus
Never heard of it. Promise to catch up :)
Welcome to knockout.js...
Nice post. It inspired me to experiment with more functional solution. The result:
https://jsfiddle.net/oshj2a...
Thanks a ton for positive feedback. I'g glad my explanation inspired you to make a cool stuff!
'more fonctionnal solution' say web dev: i only see defactorization
You learn something new every day. Thanks.
ukaszpilarski more
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!
Thanks!Stay tuned because I'm going to explain more patterns in future posts 🍿
Great explanation. Thank you 👌
Nice Post. Best and Simplest explanation of observer pattern. Thank you
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.
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.
Love ya :) Totally get it now
I am glad you found it helpful. Enjoy your day :)
:) 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?
Your codepen example says "Subscrube" instead of "Subscribe".
Thanks a lot Tristan. All fixed :-)
Finally a good guide with class ! :D thank you so much
My pleasure!
Nice post
Thanks a ton. Have a great day!
I creted this repo https://github.com/lcelso/d...
Great content and very practical. Thank you
Thanks a ton @disqus_Wmudoiw1Jj:disqus. Have a nice day!