JavaScript

How to Use the Observable Pattern in JavaScript

Lately, I’ve been trying to become more familiar with design patterns. One thing I’ve realized along the way is that it’s not easy to recognize where a specific pattern might be useful. It usually comes down to having that light bulb moment where you suddenly say to yourself “Hey! This might be a good place to use a certain design pattern.”

Define the problem.

Since design patterns are used to solve specific problems in software, let’s try to define such a problem and work to solve it using a design pattern in JavaScript.

With the rise of frameworks like React, we often hear about ‘application/component state.’ When the state is updated, components will re-render accordingly. In React, components are just a representation of what the user interface should look like.

What if we wanted to try and implement that same sort of functionality using only vanilla JavaScript? There are any number of ways to do it, but in our case, let’s explore how using a design pattern could help with our implementation.

So, let’s define the problem we are trying to solve: we need to be able to update multiple page elements when our application state changes.

In this post, we will build out a little app that allows you to add users to a list. This app will use state; so we will use the observer pattern to notify the elements that need updated when that state changes.

What is application state?

In JavaScript, state is typically just an object that holds data your application depends on.

For example, maybe you have a small app that displays a list of items it retrieves from an external API. When the app loads, it makes sense to make the API call once and store the data in app state. The app could then render based on changes to its state.

The Observer Pattern

According to Wikipedia:

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.

The observer pattern defines a one-to-many relationship. When one object updates, it notifies many other objects that it has been updated.

It’s easy to get tripped up with the subject and observer terms used in the definition above. It took me a while to wrap my head around it.

Here is a brief explanation for each:

  • subject – This is the object that will send out a notification to all of the ‘observers’ who want/need to know that the subject was updated. In our case, the subject will be the application state object.
  • observers – These are the objects that want to know when the subject has changed. In our case, these will be the page elements that need to update when the application state changes.

On a side note, the observer pattern is similar to another very popular design pattern in JavaScript, the pub/sub pattern.

Implementation

When implementing design patterns, there is often a contract that needs to be followed in order for the implementation to be correct.

What do I mean by contract? Well, in a more object-oriented language like PHP, there may be specific interfaces that the subject and observer classes need to implement. Those interfaces would in turn force any class that implements them to have the methods specified in the interface.

In JavaScript, we don’t have access to interfaces; and for the sake of keeping things simple, we create parent classes from which we can extend. The subject and observer parent classes will have those properties and methods required in order to implement the observer pattern.

Here is a basic class diagram for visual reference:

 

Subject Class

The purpose of the subject class is to maintain a list of observers that it needs to notify when it is updated. It will need the ability to add or remove observers as well.

Here is a brief explanation for the properties and methods that are required on the Subject class:

  • observers – This class property holds an array of observers.
  • addObserver() – Will push an observer on to the observer’s array
  • removeObserver() – Will remove an observer from the observer’s array
  • notify() – Will notify all observers that a change has happened

Observer Class

The purpose of the observer class is to implement an update() method that will be called by the subjects notify() method. In our case, the concrete implementation of the update() method will re-render the element.

Example Code

If you’re like me, talking theory is cool, but a concrete example is what really helps me understand what is going on.

I’ve created a very simple app that does two things:

  1. Allows users to be added to a list
  2. Updates a user count indicator when a user is added to the list

The basic flow of the app goes like this: when the new user is submitted via the input, a state change is triggered. Because the state has changed, both the list and user counter are automatically re-rendered because they are observing the state object.

Let’s walk through a few of the key files for further explanation and context.

lib/Subject.js

The subject class is one part of the observable pattern. It’s the object that will notify all of the observers that it has changed in some way.

Take note that we have an observers property plus the addObserver, removeObserver, and notify methods.

lib/Observer.js

The observer class is the second part of the observable pattern. It’s that object that gets notified when something in the subject class has updated.

The implementation for the update function is blank in this class. We will leave the implementation details to the concrete class.

lib/State.js

The state class will be the application state for our app. It extends the subject class, so in turn, it inherits all of the functions on the subject class.

On instantiation, the constructor sets the state to an empty object. The get() method just returns the state. The update() method is a bit more interesting. It will update the state and then run the notify() method passing along the updated state. This allows any observers to have access to the updated state.

components/List.js

In total, we have three components in the app. We’ll just look at the list component because the others are very similar.

The list component extends the observable class. This means that it wants to know when the application state (subject) has changed. Notice how we override the update method with an actual implementation that re-renders the component.

Below is a link to the working demo of the app. Check it out and make magic happen by adding a few users.

Click here for the demo!


Lets talk about implementing a solution like this on your website

Recap

Managing state in JavaScript is something that needs to be done frequently. If you have an app that requires updating several elements on the page when state changes, then using the observer pattern is one way you could make that happen.

Feel free to hit me up in the comments below if you have any questions or comments.

Comments

9 thoughts on “How to Use the Observable Pattern in JavaScript

  1. Crystal clear – well written! It provides me with some understanding of how Vue (et al) does its thing behind the scenes + I’ve learned about the findIndex array method. Thanks!

  2. Very concise example. Found this super valuable whlie learning about the Observer/Subject pattern. Also helped applying this paradigm towards the problems solved by react.

  3. Already looked other websites. Only your code follows observer design pattern in a simple way and easier to understand.

    Splendid job!

  4. removeObserver(observer) {
    const removeIndex = this.observers.findIndex(obs => {
    return observer === obs;
    });

    if (removeIndex !== -1) {
    this.observers = this.observers.slice(removeIndex, 1);
    }

    I don’t fully understand how this method works. Will it really remove observer from observers? Let removeIndex be 5. Then, this.observers.slice(5, 1) returns an empty array.

    1. I think possibly this.observers = this.observers.slice(removeIndex, 1); should be substituted with this.observers.splice(removeIndex, 1)

      e.g. removing index 2
      var arr = [1,2,3,4,5]; arr.splice(2,1); console.log(arr);
      > [1, 2, 4, 5]

  5. Just to add this maybe a more succinct way to do it

    removeObserver(observer) {
    this.observers = this.observers.filter( obs => obs !== observer )
    }

    e.g.
    var arr = [1,2,3,4,5]; arr = arr.filter( num => num !== 4 );
    > [1, 2, 3, 5]

  6. web design is the flexibility to adapt a website to different screens. Your website becomes easily accessible on all types of devices. Imagine your hand crafted website adjusting and optimizing automatically.

Have a comment?

Your email address will not be published. Required fields are marked *

accessibilityadminaggregationanchorarrow-rightattach-iconbackupsblogbookmarksbuddypresscachingcalendarcaret-downcartunifiedcouponcrediblecredit-cardcustommigrationdesigndevecomfriendsgallerygoodgroupsgrowthhostingideasinternationalizationiphoneloyaltymailmaphealthmessagingArtboard 1migrationsmultiple-sourcesmultisitenewsnotificationsperformancephonepluginprofilesresearcharrowscalablescrapingsecuresecureseosharearrowarrowsourcestreamsupporttwitchunifiedupdatesvaultwebsitewordpress