Professional and Affordable Web Design

0800 080 5401

Communication between objects in JavaScript applications

Some time ago, while I was working on a project I again came across a problem that resurfaces from time to time on different projects. Problem in question is object to object communication in JavaScript.

At first glance this does not seems to be something difficult to handle, on the contrary it looks to be quite straight forward. What would be simpler than to call other object's method from inside other object? All you need know is what object and what method to call. Then just place it inside desired object's method and everything is working.

As simple as it looks, above approach is sufficient only in simplest of cases. Things get more complicated when you have to interact with several objects, although this is still not that difficult to handle. But imagine a situation when you don't know how many objects you need to access, of what type (class) they are and which method you have to call. As strange and unlikely as it may seems, such situation can occur and it is not that rare.

Best example of it is a user generated list of items. Lets say that user can create several items on a list, in our case a list of vehicles. There are different types of vehicles available (like plane, car, boat) and each of them, when added, is represented by different type of object. These objects can share some of the features and methods, but undoubtly also have some unique parts in them. At the time you are writing code, you cannot tell what type of vehicles will be on the list nor how many of them there will be. With this particular example programmer can crate some code that will keep track of this items and give access to different types of vehicles or all of then when desired.

The Solution

But as I mentioned before this problem keeps resurfacing from time to time on different projects in different form. Being tired of fighting the same fire each time I tried to create a generic solution to this problem. Looking through internet for an inspiration I have encountered a solution that is already in place in several programming languages, operating systems etc.

The solution I am talking about are SIGNALS. To describe it in simple way, it is a way of sending messages to different recipients (applications, objects etc) without actually pointing out where it should go to. On other side of the process, potential recipients are 'listening', and when they 'hear' signal they recognize they are acting accordingly to it. It is like shouting to a crowd 'Who knows how to swim, go to the pool', and people who can, will go there, but while you are shouting your command, you don't really know who, if anyone, will respond.

Of course this explanation is really simple and not complete, and programmers familiar with it may laugh at it, but for our needs it is enough to start with.

Based on what I've read I decided that what I need is a JavaScript object that will handle all inter-object communication in JS. This object will receive and relay all signals.

Before I started coding it, I've set few goals this object has to achieve:

  • unified access for all objects
  • be able to pass custom data along with signal

The Code

Below is a sample code I have created for signaling in JS:

Sample code for signalling in JavaScript
var SignalBus = {

  signals: {},

  listen: function ( signal, fn ) {
    if( !this.signals[signal] ) {
      this.signals[signal] = new Array();
    }
    this.signals[signal].push( fn );
  },

  dispatch: function ( signal, params ) {
    if( this.signals[signal] ) {
      var sigList = this.signals[signal]
      for( var i = 0; i<sigList.length; i++ ) {
        this.sigList[i]( params );
      }
    }
  },

  remove: function ( signal, fn ) {
    if( !this.signals[signal] ) {
      var tmp = new Array();
      var sigList = this.signals[signal]
      for( var i = 0; i<sigList.length; i++ ) {
        if( this.sigList[i] != fn ) {
          tmp.push( this.sigList[i] );
        }
      }
      this.signals[signal] = tmp;
    }
  }

}

Above class has 4 members:

signals – an object that holds all defined signals along with pointers to functions that listens to it, it is a main 'storage' area for our object and only variable

listen – a method that is invoked when new function ( param: fn ) is going to listen for a signal ( param: signal ).

dispatch – a method used to actually call a signal with any arguments passed to it. Arguments has to be in a form of an array. Any function associated with it will be called with passed arguments.

remove – oposite to listen, remove function from listeners list.

The example of using this class is below:

Example use of class
var Object1 = {

  start: function () {
    SignalBus.listen( 'SIGNAL_DO_SOMETHING', function ( args ) { Object1.doSomething.apply( Object1, args ); } );
  },

  doSomething: function ( a, b ) {
    alert( a + ' has done something to ' + b );
  }

}

var Object2 = {

  start: function () {
    SignalBus.dispatch( 'SIGNAL_DO_SOMETHING', [ 'John', 'Jane' ] );
  }

}

Object1.start();
Object2.start();

In this example, Object1 listens for a signal and Object2 dispatches it.

The Conclusion

It may look a bit odd to create all this code just to call a method from one object from within an another one.

To appreciate it, think of a situation when you need to add another object that will react to the same signal, but you don't want to change anything in existing code. Without signals, you couldn't do it, as you would have to modify Object2.start() to accommodate for another object. With signals implemented, all you have to worry about is to remember while coding new obhject to make it listen to proper signals, older code does not have to be updated.

Also, if presence of object that will listen to a signal is not hardcoded, in other word it depends on user's actions there is no need to add any detection code in dispatching object, if this object does not listen, or does not even exist, nothing will happen.

Signals is a simple and flexible solution, which programmers will aprreciate more and more as their applications grow in size. Above code is just an example, it can be improved in many ways, but even in this basic and simple form it can be really useful.

Useful links

Comments1 Comments

Jeff

This is a nice observer pattern for javascript. I find this is really useful for maintaining loose coupling between parts of a web application. Thanks for sharing this. One note though in your remove method this: if( !this.signals[signal] ) should be: if( this.signals[signal] )

21 March 2010

All comments are moderated for spam and will not be shown. All genuine comments wil be show, however the links will be based on a NO FOLLOW RULE. Repeat commenters adding value to the articles and discusions will have removed alowing Follow Rule to Work.

Make a Comment

Notify me when someone responds

Quick Contact

See Full Portfolio Some Of Our Work

Screenshot of dsbs.co.uk website
dsbs.co.uk

Driving Schools Booking Service (DSBS) is a network of driving instructors, covering the whole of the UK. For this project, we were...

Screenshot of countysecurity.co.uk website
countysecurity.co.uk

County Security is a fully featured E - commerce solution, with an integrated "system configurator", which allows users to choose...

Customer News & Resources

At Mutiny Design we are constantly gathering together articles and help guides to assist our clients.

Introduction to sitemap.xml

Checking for a sitemap A site map (or sitemap) is a list of pages of a web site accessible to crawlers or users. It can be either a document in any form used as a planning tool for web design, or a web page that lists the pages on a web site, Some developers feel that site index is a more appropriately used term to relay page function, web visitors are used to seeing each term and generally associate both as one and the same. However, a site index is often an A-Z index that provides access to content, while a site map provides a general... Read More »

Center a web page in CSS

One simple way to center a web page using CSS is to create a container div, that is horizontally centered by having its left and right margins set to auto. Using this method, you can still apply colours / background images to the body tag, so its a flexible solution. (if you didnt need this ability, just apply margins and width to the body tag instead, and forget using the container div). The container div has the same width as your webpage and, well, contains it. All the code for your web page is placed inside the container div. This will... Read More »

-