Archive for January 2009


Custom JavaScript Events with the Observer Pattern

January 28th, 2009 — 1:34pm

Anyone that’s worked with JavaScript in the browser knows that it’s all about events.  And in our daily work with the DOM we use the provided events like “click”, “change”, and “load” all over the place.  But what if you want to create new events for custom objects that might not even have any associated UI.  Unfortunately, the W3C standard for custom events in JavaScript has spotty implementation across browsers, or none at all in some cases.

So, what are we to do…well…here’s a simple implementation of the observer pattern that can help solve the lack of internal support for custom events.  Here’s the Observer “classes”:

var Observer = function() {
    this.observations = [];
};
 
var Observation = function(name, func) {
    this.name = name;
    this.func = func;
};
 
Observer.prototype = {
    observe: function(name, func) {
        var exists = this.observations.findAll(function(i) {
            return i.name == name && i.func == func; }).length > 0;
        if (!exists) { this.observations.push(new Observation(name, func)); }
    },
    unobserve: function(name, func) {
        this.observations.remove(function(i) {
            return i.name == name && i.func == func;
        });
    },
    fire: function(name, data, scope) {
        var funcs = this.observations.findAll(function(i) {
            return i.name == name; });
        funcs.forEach(function(i) { i.func.call(scope || window, data); });
    }
};

First thing you’ll notice is methods on the “observations” array like forEach() and findAll().  These methods are added by my set of JavaScript extensions found in a previous post.  You’ll also notice that this is very simple…so simple in fact that I’m not going to go through it line-by-line…I’m just going to demonstrate.  Here’s how you might use this object:

var Person = function() {
 
    this.name = "John Doe";
    this.age = 23;
    this.observer = new Observer();
 
    this.changeName = function(newName) {
        this.name = newName;
        this.observer.fire("nameChanged", newName);
    };
 
    this.changeAge = function(newAge) {
        this.age = newAge;
        this.observer.fire("ageChanged", newAge);
    };
};
 
var p1 = new Person();
var p2 = new Person();
 
p1.observer.observe("nameChanged", alertNameChanged);
p2.observer.observe("ageChanged", alertAgeChanged);
 
function alertNameChanged(data) { alert("name changed to: " + data); }
function alertAgeChanged(data) { alert("age changed to: " + data); }
 
p1.changeName("James Doeson");
p2.changeAge(35);

Super simple…create an observer, observe a few things by name, fire a few things by name.  So now you have a behavior very similar to custom events.  One thing to note is that you can change the scope of the callback by passing a third parameter to the observe() method.  So, if you want this to reference some different object within the callback function, just pass it in.

Comment » | JavaScript

Useful JavaScript Extensions

January 25th, 2009 — 5:24pm

Over the years I’ve collected a set of useful extensions to the Object, Array, and String constructs in JavaScript and I thought I might publish them.  They are all pretty simple but it’s a pain to have to write these over and over for each new project so I just compiled them into on file and off we go.  There are probably improvements that could be made to these methods and new ones to be added so please feel free to share your ideas and I’ll incorporate them back in.

Here is a listing of all the methods that this file adds:

ObjUtil.isString(Object)
ObjUtil.isNumber(Object)
ObjUtil.isBoolean(Object)
ObjUtil.isArray(Object)
Object.isFunc(Object)
ObjUtil.isDate(Object)
ObjUtil.isRegEx(Object)

ObjUtil.addOverload(Object, String, Function)
This function adds some pseudo function overloading to JavaScript.  The first argument is the name of the function you’d like to expose and the second is the function to be called using that name.  The limitation here is that the only way to distinguish between method implementations is by the number of arguments (JavaScript does not discriminate by type or name).  Thanks to John Resig for the inspiration for this method.

var obj = { };
obj.addOverload("doSomething", function(a) { ... });
obj.addOverload("doSomething", function(a, b) { ... });
obj.doSomething(a);
obj.doSomething(a, b);

ObjUtil.compareTo(Object, Object)
A generic comparison method that can be used in sorting functions.  Handles differences in lexicographical order of strings by converting to lower case.

Function.partial()
Adds partial function capability through simple currying.  Thanks to Oliver Steele’s Functional.js library for this method.

var add = function(a, b, c) { return a + b + c; };
var addPart = add.partial(1, undefined, 3);
alert(addPart(2)); // alerts 6

String.toBoolean()
Converts the following values to true/false: “true” or “1″.

Array.copy()
Copies an array’s contents to a new array.  Keep in mind that if the array isn’t made of simple types like string, number, or boolean that the new array will contain references to the old array’s objects.  However, using the copy facilitates sorting and other mutations without affecting the original array.

Array.forEach(Function)
Takes a in a function and calls that function once for every item in the array.

var arr = [1,2,3];
arr.forEach(function(i) { alert(i); });

Array.find(Function)
Takes a function that returns a boolean and returns the item that matches the functions criteria.  If more than one item match the first one is returned.

var arr = [{name:"Bill", age:17}, {name:"Bob", age:27}, {name:"Brian", age:34}];
var item = arr.find(function(i) { return i.name == "Bob"; });

Array.findAll(Function)
Takes a function that returns a boolean and returns an array of all items matching the functions criteria.

var arr = [{name:"Bill", age:17}, {name:"Bob", age:27}, {name:"Brian", age:34}];
var items = arr.findAll(function(i) { return i.age > 25; });

Array.contains(Object)
Tests if an array contains a certain item, returns a boolean.

Array.distinct()
Returns a new array of distinct values from the source array.

Array.min()
Returns the minimum alpha-numeric value in the array.

Array.max()
Returns the maximum alpha-numeric value in the array.

Array.first()
Returns the first item in an array or null if the array is empty.

Array.last()
Returns the last item in an array or null if the array is empty.

Array.sortAscending()
Sorts the array in ascending numerical or lexicographical order depending on if the first item in the array is a number or not.

Array.sortDescending()
Sorts the array in descending numerical or lexicographical order depending on if the first item in the array is a number or not.

Array.randomize()
Randomizes the order of the array.

Array.count(), Array.count(Function)
Returns the number of items in the array.  If a function is passed in it counts the items matching the functions criteria.

var birds = [{name:"Bill", birdType:"ostrich"}, {name:"Bob", birdType:"penguin"}, {name:"Brian", birdType:"penguin"}];
var penguinCount = birds.count(function(i) { i.birdType == 'penguin'; });

Array.except(Array)
Takes two Array objects and returns a new array of only the items that are unique to both of the first two.

var arrA = [1,2,3,4,5];
var arrB = [3,4,5,6,7,8];
var itmes = arrA.except(arrB);

Array.intersect(Array)
Takes two Array objects and returns a new array of only the items shared between the first two.

var arrA = [1,2,3,4,5];
var arrB = [3,4,5,6,7,8];
var itmes = arrA.intersect(arrB);

Array.average()
Returns the average numeric value in the array.

Array.sum()
Returns the sum of the numeric values in the array.

Array.union(Array)
Returns a new array after joining two others but does not include duplicates.

var arrA = [1,2,3,4,5];
var arrB = [3,4,5,6,7,8];
var newArr = arrA.union(arrB);

Array.safePush(Object)
Adds an item to an array but only if that item doesn’t already exist in the array.

Array.getRandom()
Returns a random item from the array.

Array.insertAt(Number, Object)
Adds an item to an array at the specified position (first parameter).

Array.remove(Function)
Removes items matching the functions criteria from the array.

var arr = [{id:1, name:"Bob"}, {id:2, name:"Tom"}, {id:3, name:"Jim"}];
arr.remove(function(i) { return i.name == "Tom"; });

Array.indexOf(Object)
Returns the index of the item in the array or -1 if the item isn’t found.

Download JavaScriptExtensions.zip

Note: There is a “tests.html” file which contains examples and unit tests for all of these extensions.  The unit tests are written for FireUnit for FireBug.

3 comments » | JavaScript

A Study in Patterns: The State Pattern

January 20th, 2009 — 11:06pm

I'm a big fan of software development patterns.  They're an excellent way to get the ball rolling when you're faced with a puzzling design situation.  But sometimes they're difficult to grok and it can be confusing to know when and how to implement just the right pattern for the circumstance.  So to improve my own skill and knowledge with patterns I'm going to start a series of posts exploring some useful patterns – undoubtedly these posts will be as much for me as anyone who reads them.

One of the patterns I've recently found useful is the State Pattern.  If you've ever used an enumeration to define or transition an object's state, or written an elaborate switch statement with nested "if" blocks to modify an object's behavior depending on its state then the State Pattern might be right up your ally.  The GoF defines the State Pattern as:

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

This definition is all well and good (and I might argue with the "change its class" business), but how would you actually implement such magic.  Let's use the following model as an example:

State-pattern-class-diagram

The basic premise is that we hide changes in our implementation of methods like "Graduate" and "IssueTranscript" behind the private field "_state" which is a reference to an IStudentState.  Our public methods Student.Graduate() and Student.IssueTranscript() call the implementations of _state.Graduate() and _state.IssueTranscript().  If _state happens to be an instance of ApplicationState then IssueTranscript() will likely perform a different action than if _state was a GraduatedState.

Another thing you'll notice is the reference that the "state" classes have back to Student.  There are likely alternate implementations of this pattern that avoid this backward reference, but you might find that you need some context in your implementation methods within the state classes.

So you can begin to see how this can reduce the amount of complex switch/if logic you'll have.  It may seem like it adds complexity in that you have more classes to content with, but after using this pattern a few times you'll be grateful of the clean segregation of behaviors achieve with the State Pattern.

Comment » | General Programming

You Can Never Go Back

January 15th, 2009 — 10:31am

Sometimes when I'm wrestling with a particularly irritating CSS problem (usually caused by certain flavors of IE) I find myself pining for ye-good-ol'-days of table based layouts.  I find the little devil on my shoulder yelling…"hey stupid, just use a freaking table."  Then I go to the following URL and regain my sanity:

http://www.shouldiusetablesforlayout.com

Comment » | Randomized

Integrating Adobe Flex and .NET with ASP.NET MVC

January 2nd, 2009 — 3:30pm

There are a lot of tools out there to help you utilize .NET as a back-end for Flex applications.  All of these solutions come with a heavy customization and implementation cost.  I’ve used WebORB with quite a bit of success in the past but it always seemed a little heavy to me.  The truth is that WebORB and its compatriots are the right choice for large applications or apps with highly complex server side needs.  But for the lightweight web application that doesn’t require tons of server side business logic there is another choice.

With the advent of ASP.NET MVC we have a very simple way to construct web accessible .NET endpoints – controller actions.  In the past when you needed to get data out of .NET using HTTP you might spin up a web service or a WCF service.  These are still great options, but if the data you need to transfer is small and/or jagged you might find yourself writing a lot of extra code.  You’ll also pay the XML tax and nobody likes paying taxes.

So if not XML, what then?  Well, JSON of course.  JavaScript Object Notation is a perfect media for transmitting moderate amounts of data over the wire.  And there are excellent serialization options on both the .NET and Flex sides of the game.  So here’s a little example of this pattern in action.

Create an ASP.NET MVC Controller Action – Return JSON.

public ContentResult GetInventory() {
var repository = new InventoryRepostiory();
var items = repository.GetItems().ToList<InventoryItem>();
return Content(items.ToJSON(null));
}

I’m not going to go into the data access pattern here in this article, but I’m using a repository to return a set of inventory items.  You might also be wondering where this ToJSON() method comes from.  It’s an extension method…and here it is (c/o ScottGu):

public static string ToJSON(this object thing, int? recursionDepth) {
    var serializer = new JavaScriptSerializer();
    if (recursionDepth.HasValue)
        serializer.RecursionLimit = recursionDepth.Value;
    return serializer.Serialize(thing);
}

All it does is take an object, do a little reflection magic on it via the System.Web.Script.Serialization.JavaScriptSerializer class and spits out a JSON string.

Calling Your ASP.NET MVC Controller Action from Flex

The first thing you’ll need on the Flex side before you can consume your MVC action is a way to de-serialize the JSON string.  Fortunately, the Adobe guys have provided a handy library of utilities called AS3CoreLib which contains just such a service.  Once you have the SWC just pop it in the Libs folder of your Flex app.

So now let’s create a wrapper class in ActionScript to consume our ASP.NET MVC action.  I like to mimic the repository pattern on the Flex side as well so that I can keep up with a somewhat consistent API.  There’s nothing that technically holds you to this rule, but it’s helpful to keep things logically organized.  So, here’s the InventoryRepository in AS3:

package Data {
    import com.adobe.serialization.json.*;
    import flash.net.*;
    import flash.events.*;
    import mx.collections.ArrayCollection;
 
    public class InventoryRepository {
 
        private var completeCallback:Function;
 
        public function GetInventory(callback:Function) : void {
            completeCallback = callback;
            var loader:URLLoader = new URLLoader(new URLRequest("http://localhost/Home/GetInventory"));
            loader.addEventListener(Event.COMPLETE, getInventoryComplete);
        }
 
        private function getInventoryComplete(event:Event) : void {
            var obj:Object = JSON.decode(event.target.data);
            completeCallback(obj);
        }
    }
}

You’ll notice that I’ve imported the com.adobe.serialization.json classes from AS3CoreLib.  That provides us with the JSON.decode() method.

Now, because remote calls in Flex are asynchronous, we need to do a little fancy footwork to deal with it.  So, when you call the GetInventory() method we also have to supply a callback to fire off when the data returns from the MVC action.  This is one of my favorite aspects of ActionScript…it’s dynamic…dynamic in the JavaScript sense of the word.  So we can supply a callback that doesn’t need to be defined in our repository class itself. 

So let’s look at some code that consumes our repository method.  This is just a code-behind file for an MXML appl ication:

package InventoryApplication {
    import mx.core.Application;
    import flash.events.Event;
    import mx.controls.DataGrid;
    import mx.collections.*;
    import Data.*;
 
    public class HomeApplication extends Application {
 
        public var inventoryGrid:DataGrid = new DataGrid();
 
        public function InventoryApplication() {
            super();
            LoadInventory();
        }
 
        public function LoadInventory () : void {
            var repository:InventoryRepository = new InventoryRepository ();
            repository.GetInventory(function(data:Object) : void {
                inventoryGrid.dataProvider = data;
            });
        }
    }
}

So the only really interesting thing here is how we’re defining the callback as an anonymous function passed into the GetInventory() method.  When the data is returned we just bind it to our data grid and we’re done.

Sending Data To an ASP.NET MVC Action From Flex

So, now we can pull data out of our .NET back end, but how do send data into an MVC action from Flex?  The solution couldn’t be simpler.  So here’s a new method for the AS3 repository:

public function CreateKind(itemName:String,
    itemType:String,
    itemSize:String,
    callback:Function) : void {
 
    var variables:URLVariables = new URLVariables();
    variables.name = itemName;
    variables.type = itemType;
    variables.size = itemSize;
 
    var request:URLRequest = new URLRequest("http://localhost/Home/CreateKind");
    request.method = URLRequestMethod.POST;
    request.data = variables;
 
    var loader:URLLoader = new URLLoader(request);
}

Here you can see we’re passing in the properties of our new item and adding them to the variables object directly (another nice thing about ActionScript being dynamic).  So now these new properties will become variables in the form collection sent to our controller action.  Here’s our controller action:

public ContentResult CreateItem(string name, string type, string size) {
 
    var item = new InventoryItem
    {
        Name = name,
        Type = type,
        Size = size
    };
 
    var repo = new InventoryRepository();
    repo.SaveItem(item);
 
    return Content("true");
}

You’ll notice that the parameters it accepts are “name”, “type”, and “size”.  These are the same properties added to the Flex URLVariables object in our Flex repository class.  Through the magic of ASP.NET MVC these items are simply available to the controller action as parameters, simple as that.

So, hopefully that demonstrates how easy it is to use ASP.NET MVC to integrate a .NET back-end with Flex.  I think the advantages of this method are substantial, but do your research and take a look at the other options as well.

5 comments » | ASP.NET, ASP.NET MVC, Flex

Back to top