Introduction
A diabolical herd of pigs stole all of the front-end architecture from an innocent flock of birds and now they want it back!
A team of special agent hero birds will attack those despicable pigs until they recover what is rightfully theirs, front-end JavaScript architecture!
Will the birds be successful in the end? Will they defeat their bacon flavored foe? Let's find out together in another nail biting episode of Angry Birds of JavaScript!
Check out the series introduction post for a list of all the birds and their attack powers.
Previous Attacks
Blue Bird Attack
In this post we will take a look at the Blue Bird who triggers events and messages that scatter to infiltrate the pig's castle. Slowly, one by one, the birds will take back what it theirs to keep!
What Was Stolen by the Pigs?
The birds used to build their web applications with components having hard dependencies on each-other. They eventually started to learn to reduce tight coupling by introducing events and messages. Unfortunately the pigs, during their invasion, stole the birds' observer secrets.One of the blue birds has been tasked with taking back what has been stolen and restore loose coupling components.
Sample Application
In order to unpack the need for messages we will look at the following web application to search for movies from Netflix. We will uncover how this application was originally coded and then refactor along the way.
Tightly Coupled Code
The first version of the above application was coded using the following JavaScript code. Take a look at the code and let it start to sink in for a little bit. It may be painful, but please bar with me for a moment ;)
The above code sample is a typical jQuery example that you can find across the internet. The snippet works, but there is a lot of different things happening all in the same place. You can find event handling, data retrieval, and data manipulation all mixed together. You can imagine that over time this code might continue to grow and grow and become more and more prone for errors.
Before we get too far, let's take a side trip and look at what messages are and what types exist.
Types of Messages
Observer Events
An observer event is probably one that you are most used to if you are familiar with front-end web development. In relation to the DOM you can think of this as adding event handlers to an element. The element has a direct reference to the callbacks that will be invoked when the event type occurs.
Example
Mediated Events
A mediated event or message has become more common the last several years in front-end web development. The main idea here is that there is another entity that keeps track of publishing and subscribing of messages. The main difference between this and Observer events is that Mediated events aren't tied directly to the subject that invoked it.
Example
Implementations
There are several libraries out there that facilitate mediated events. The following is a list of various libraries that you may want to choose from. My recommendation is that you look at Jim's postal.js library.
- Ben Alman's (@cowboy) Tiny jQuery Pub/Sub library
- Peter Higgin's (@phiggins) pubsub.js library
- Jim Cowart's (@ifandelse) postal.js library ← Recommended
- Dustin Diaz's (@ded) reqwest library
- appendTo's (@appendTo) AmplifyJS Pub/Sub component
Hybrid Events
There is another type of event that is sort of a hybrid between observer and mediated. This type looks like a mediated event, but if you look hard enough there you could actually trace the origin of the event back to the original subject. A good example of this is jQuery's delegated event model. Delegated events are great, but it is based on the concept of events bubbling up the DOM and therefore we can trace where it came from.
Example
By the way, I don't recommend using the
$._data()
method as it is undocumented and therefore not guaranteed that it will be available in future versions of jQuery. It is an internal helper method that jQuery currently uses under the covers. However, I did want to show you that there is a way to poke around and get at information that the subscriber shouldn't have in a real "mediated event", which is why I'm calling it a hybrid event. Don't get me wrong, I love jQuery's delegated events. I just wanted to show how it is a hybrid of the two above concepts.Which One Should Be Used?
That information is all fine and good, but what type of event/message should you be using and when? That is a great question and one that my friend Jim addressed in a recent post that he wrote. The following is a quote from his article...
"...use observer 'locally', inside a component, mediator 'remotely' between components. No matter what, be ready to use both in tandem.' --Jim Cowart
Jim recommends using observer events (jQuery's
.on()
method) when communicating within a module and to use mediated events (postal.js) when communicating between modules.Another technique that Jim brings up in his article is to promote observer events into mediated events, which gives you the both of both worlds. He has some nice examples showing how that could look. I encourage you to take a look at his article referenced below in bold.
Additional Resources
If you are interesting in more information about the above concepts you may consider looking through some of the following resources about events and messaging.
- Jim Cowart's (@ifandelse) Client-side Messaging Essentials article
- Addy Osmani's (@addyosmani) Understanding the Publish/Subscribe Pattern for Greater JavaScript Scalability article
- Rebecca Murphey's (@rmurphey) Loose Coupling with the pubsub Plugin screencast
Loosely Coupled Code
I was tempted to write the following code using Backbone.js or create constructor functions, but in order to keep it simple and convey the idea of messaging I tried to remove all of that. So, this probably isn't what you'd have in your code-base, but hopefully it gets the point across.
Attack!
The following is a simple Angry Birds clone using boxbox, a framework for the box2dweb JavaScript physics library, written by Bocoup's Greg Smith.
Press thespace bar
to launch the Red Bird and you can also use the arrow keys. If it takes you too long to destroy the pigs you might want to consider pressing thespace bar
several times ;)
Conclusion
Using events and messages across your web application can help with communication. Events allow a component to communicate with itself and messages can enable other components to listen in without having a hard dependency.
There are many other front-end architecture techniques that have been stolen by the pigs. Tune in next time as the next Angry Bird takes its revenge! Dun, dun, daaaaaaa!