Tag Archives: JavaScript

Sorting through long and cluttered JavaScript code with MVP

JQuery is a wonderful tool for JavaScripters and it’s been around for years, showing its true power and simplicity. But even jQuery falls short of solutions when the web site/application grows in size and complexity.

After writing a lot of JavaScript code on a web application, it becomes more obvious that the direct way of doing it is not the right way and ends up having code no one understands anymore.

So how to get rid of the JavaScript clutter? Enter MVP!

Model View Presenter

Actually it’s all about separation of concerns. The problem with most code is it mixes 3 aspects:

  1. AJAX calls
  2. DOM manipulation
  3. Event handling

We can call them the Model, the View and the Presenter and instead of putting them together in one place, we can define separate objects for each.

Let’s see how the code may look like on a page that performs an async search.

The Model

var model = {
  searchWebsite: function(searchQuery, handlers) {
    $.ajax({
      url: "/search",
      type: "POST",
      data: "q="+searchQuery,
      success: handlers.success,
      error: handlers.error
    });
  }
};

This guy is only responsible for sending the search query to the server, to the right URL and using the right method (POST). He will not interpret the response to populate the page with the results, for example. That’s not his problem. He only manages server calls.

The View

The View, on the other hand, he knows about how things are arranged on the page. He’s really good at finding stuff in the DOM tree, moving things around, changing styles and so on. In our example, he’ll be responsible for installing a handler on the search button, providing the search query and, later on, putting the results where they belong.

var view = {
  installSearchHandler: function(searchHandler) {
    $("#searchButton").click(function () {
      var searchQuery = $("#searchQuery").val();
      searchHandler.call(this, searchQuery);
    });
  },

  showSearchResults: function(searchResults) {
    for (aResult : searchResults) {
      // create a DOM node and show the aResult in it
      $("#searchResults").append('<p>'+aResult.title+'</p>');
    }
  },

  showSearchError: function(error) {
    $("errorDiv").show();
    $("#errorDiv #errorMessage").html(error);
  }
};

The Presenter

This guy is responsible for putting things together, he’s the middle man, deciding the flow of the page. The Presenter will install the listeners into the View and send requests to the Model to retrieve or send data from and to the server. An important aspect of the Presenter is that he’s aware of the other 2.

var presenter = {
  init: function() { // start from here (page load)
    view.installSearchHandler(this.search);
  },

  search: function(searchQuery) {
    model.searchWebsite(searchQuery, {
      success: function(data) {
        view.showSearchResults(data.searchResults);
      },
      error: function(data) {
        view.showSearchError(data);
      }
    });
  }
};

Starting up this chain of objects

The presenter.init() is supposed to start up this whole deal, from there on, he’ll handle everything and delegate tasks to the view or model as appropriate. We can use jQuery document ready for this:

$(document).ready(function() {
    presenter.init();
});

And we’re done!

What’s the gain?

Now that we’ve implemented our search the MVP way, let’s take a moment and look at our accomplishment. Why did we do this? What is our gain? If that’s not obvious, let’s see how the code would have looked without structuring it the way we did:

$(document).ready(function() {
    $("#searchButton").click(function () {
      var searchQuery = $("#searchQuery").val();
      $.ajax({
        url: "/search",
        type: "POST",
        data: "q="+searchQuery,
        success: function(data) {
          for (aResult : data.searchResults) {
            // create a DOM node and show the aResult in it
            $("#searchResults").append('<p>'+aResult.title+'</p>');
          };
        },
        error: function(error) {
          $("errorDiv").show();
          $("#errorDiv #errorMessage").html(error);
        }
      });
    });
});

Everything is put together in one place, making it harder to read and understand what is all about.

On the other hand, if we look at our presenter, we understand immediately what the page is supposed to do: search by a searchQuery and, in case of success, showSearchResults, in case of error, showSearchError. You notice we used words from the code itself to explain what the page does – that’s because the code sounds more like an English language phrase than cryptic JS code.

In the real world out there, the code grows a lot more, as well as the clutter. Out there, this design will prove even more useful while our counter-example – even worse.

Why JavaScript scares the hell out of the Java developers?

Today there is a clear tendency to move more and more of the presentation logic on the web client side. Yeah, that means the web browser. So if you want to get a slick Web 2.0 interface for your cool website, then you need to bring in the horror named JavaScript. Well, it’s a horror if you’re a Java developer… So why do we fear it?

Fear of the unknown

Fear of the unknown

Fear of the unknown by zephirance

Oh yeah, we all fear the unknown, so after years of Java, the weird scripting language that has a similar name only by chance, fits well between our darkest fears. They say it’s object oriented, but I can’t use the class keyword and heck if I know how to declare a class. And then the var type freaks me out because I love my favourite concubine – static typing. And undefined? Jeez! What’s wrong with plain ol’ null?

OK, I admit I was part of the group of Java developers that were afraid of this strange JavaScript stuff and I din’t like myself very much for it. I had to do something to change this so I tried reading a few good books on it, especially those for beginners. Because you see, JavaScript is nothing like Java and you really need to start from the beginning.

I learnt there are no classes in JavaScript but only objects. For someone coming from the Java world, this is quite a different approach. Don’t define a class and then create instances of it, as many as you like. Instead you get to define your instance directly by adding properties (already initialised with values) and functions. And should you need to create another object of the same kind, just copy its prototype from the previous one. Hm, that’s something! It can get you into a lot of trouble of you misuse it, but handling it with love – brings joy to your boring life and a touch of craziness, of freedom.

// declare the object directly
var aLovelyObject = {

	name: "lovely",
	purpose: "make love not war",

	givePurpose: function(newPurpose) {
		this.purpose = newPurpose;
	},

	rename: function(newName) {
		if (newName != undefined) {
			this.name = newName;
		}
	}
};

// use the instance we declared above
aLovelyObject.rename("hateful");
aLovelyObject.givePurpose("promote darkness");

Isn’t that just lovely? And if we need another object of the same kind (whatever that would be), we have a lot of options out there that basically copy the kind (which we should call prototype) to our new instance. Even change it afterwards. I personally like JQuery style:

var anotherLovelyObject = $.extend({}, aLovelyObject);

We can even add some more properties and functions to the new object:

var anotherLovelyObject = $.extend({}, aLovelyObject, {

	speak: function() {
		if (this.name == "lovely") {
			alert("I love you");
		} else if (this.name == "hateful") {
			alert("I hate you");
		} else {
			alert("I'm confused");
		}
	}
});

So our second lovely object can speak now, while our initial one cannot. Very smart!

To me there’s no reason to dislike JavaScript because if you get to know it well enough it will surprise you with it’s abilities, help you write less code and make a lot of sense through it.

How to get to know JavaScript better – tests

Of course you can start reading about it. Here is a bunch of books that can prove useful:

JavaScript: The Good Parts

Image by nyuhuhuu via Flickr

Well, if you really are on to it, the best way to explore it is through tests. You can write tests in JavaScript too, just like you do in Java, you can even use Continuous Integration. There is a fantastic book that explains very well how to start looking at the tests in JavaScript, what your options are and how to approach this. So try to pick up Test-Driven JavaScript Development by Christian Johansen.

Good luck!