Site icon WebDevStudios

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:

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:

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.

See the gist on github.

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.

See the gist on github.

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.

See the gist on github.

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.

See the gist on github.

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!



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.

Exit mobile version