Understanding JavaScript Observer Patterns

Understanding JavaScript Observer Patterns

There’s a lot of love and hate talk when it comes to object-oriented programming. Don’t get me wrong, OOP has both its perks and quirks — but at the end of the day, it’s only as good as your design patterns.

A lot of us only get to know OOP on a surface level. Many of us rarely go beyond the bare-bones basics of making objects and using inheritance to make things work. OOP beyond inheritance in the self-taught circles is almost unheard of — unless the developer has taken initiative and gone beyond the usual stock of YouTube tutorials.

In this piece, we’re going to go over an OOP design pattern called the observer pattern that can help you think about your code as a logical and structured piece of idea rather than just something with methods attached to it.

Design patterns in a nutshell

Design patterns are codified methodologies of thinking. It is not exactly language exclusive but is applicable to all languages that has a certain structural feature enabled.

This means that rather than just creating code based on the default and seemingly obvious path, design patterns makes you take a step back, away from the code, and towards the logical thinking portion of the code creation process.

As a result, your thinking process is able to ascribe to different modes of logic and its implementation based on context, current, and future requirements.

And with this knowledge and ability, a developer is able to make code less entangled and more structured in nature. It also allows the code to be flexible, rather than brittle when changes and pivots in requirements are introduced.

This is why we use design patterns and how it can help us work much more effectively, as much as it can help us with our team based code coordination and cohesive construction abilities.

One of these patterns is the observer pattern.

How to observer pattern works

The observer pattern consists of three ingredients — the “subject”, the observer, and the objects.

The relationship between these three ingredients works like this: think of the subject as the central piece of code that ultimately controls the running of everything. The observer acts as a holding list for all the relevant objects.

Objects are subscribed to the subject and wait for the subject to call it. Objects are unsubscribed when it’s no longer needed.

Why is this a good thing?

Imagine you want to update a collection of things when something updates from a particular source. However, you don’t want to call your object, function or method every single time something happens.

Imagine you have about fifty of these objects/functions/methods.

The observer pattern lets you consolidate and call whatever you want from a single source.

And that’s basically it in a nutshell.

The Observer Pattern Recipe for JavaScript

The observer pattern in JavaScript is super easy. You just need to set up a subject function and extend it using prototypes.

If you’re sketchy on how prototypes work, here’s a quick guide I wrote previously on the topic.

In short, everything in JavaScript is an object and prototypes lets you create extensions via methods

To set up the observer pattern in JavaScript, you need to create a subject and three methods attached to it. These three methods are subscribe, unsubscribe, and fire

subscribe and unsubscribe lets you attach and detach functions you want in the observable holding list. fire is the method call you use to run your functions.

Here’s the code:

function Subject(){
 this.observers = []; //array of observer functions 
}

And now for the methods:

Subject.prototype = {  
   subscribe: function(fn)  
   {    
     this.observers.push(fn)  
   },  
   unsubscribe: function(fnToRemove)  
   {    
      this.observers = this.observers.filter( fn => {      
         if (fn != fnToRemove)        
               return fn    
      })  
   },  
   fire: function()  
   {    
      this.observers.forEach( fn => {
         fn.call()    
    })  
}}

And that’s basically it.

Now all you have to do is create your functions and then subscribe them to the observable list. Here are some example functions:

function ObserverTest(){  
   console.log("observer test works!")
} 

function AnotherFunction(){  
   console.log("it works again")
}

To subscribe, be sure to create a new Sujbect() object to instantiate and contain your list.

Using the subscribe method we’ve set previously, add the function as a parameter into the subscribe()

We can now use fire() on subject to run all our functions at once.

//subscribing the functions
const subject = new Subject();

subject.subscribe(ObserverTest)
subject.subscribe(AnotherFunction)

//runing all the subscriptions once
subject.fire()

Observer Pattern in real life

You must be thinking, where can we actually use this in real life?

The observer pattern is actually quite popular and due to the nature of JavaScript being closely linked to visual interfaces, the observer pattern is often implemented to coordinate the update of views.

This means that your views can be broken up into component parts and updated only when necessary.

With the observer pattern, it allows your code to be broken up into manageable parts and reusable.

How?

Imagine a component of a view that you want to reuse across multiple pages. However, you only want to code it once and depending on the page, it may be taking in data from different sources.

How do you keep them separate and isolated but still able to reuse it?

By subscribing the same component view to different subjects, you are able to achieve this effect.

In addition to this, the subject can have multiple view components it coordinates, and pushing out updates in one call rather than having to individually update them when something changes.

Final thoughts

When it comes to code reusability and coordination, the observer patterns makes a good candidate in JavaScript.

The point of the observer pattern is to instigate change in one call rather than many. As a result, it reduces the overhead of coding and calling things, and therefore helping you create code that is much more succinct in nature.

And that’s basically it.

💡
Want to sponsor matcha.fyi? You can have your brand featured right here. Let's connect and chat about it.