Home » Programming » Archive by category "JavaScript"

Intro to Backbone Routing

Routing is a method of triggering state. In your site you have paths that bring a user to different pages that provide specific content. Routes are just like that but for a single page. They provide a way to trigger a specific state on that page. A good example is search.

Assume that a page may shows a list of items the user has ordered. For that the path could look like “www.mySite.com/user/orders/2012/”. We assume there is a view in that page that will show the details the orders that match a search term a modal. The page could have script that searches though the data, using Underscore.js possibly, to produce the select orders and then launch a modal to show them. A route can be the trigger to perform the search and show the modal. Afterward the route in the app can then be used by the user to book mark the result with out the general mess of a search/query string in the URI. The resulting URI would look something like this “www.mySite.com/user/orders/2012/#search/orange” for the users search for orders with the keyword “orange” in them. As a application gets more complicated in its views and states routes become a good way to trigger and return to specific sates in your application.

So how do you get started with Routes?

First start to extend the route class:

var PageRouter = Backbone.Router.extend({});

The route extend function takes a hash as its parameter. The hash has key with all the routes and keys for the functions the routes will call when they are matched:

'routes': { //Key for routes followed by the route map
    'pathOne/someThing/:aValue': 'RouteOne', //path and trigger name
    'pathTwo/*everything': 'RouteTwo'
},
//Each trigger name and action for the path mapping
'RouteOne': function (aValue) {
    //Do Something
}

The last part is to create an instance of your router and then to start the backbone history module.

var pRte = new PageRouter();
Backbone.history.start();

Navigating to a route will trigger the function its bound to to run. The function will be passed all the keys defined in the path as and parameters. Key can be either specific parts of the path or splats of what ever is left. Keys are defined like “reports/:year/:month/:day/” where the function that is called when that path is matched could have the parameters (year, month, day).

The last thing to note is that routes are matched from first to last. So if you define “search/ducks”, above “search/*term” the latter will never respond to a path of “#search/ducks” because the first route will catch it. That being said making the last route “*anything” is a good way to catch all the routes that don’t match anything else.

The Ternary Operator as If / Else Shorthand

In my last post i created the following piece of code to group names from a list into a hash by their first letter. Looking at I though about how it could be reduced to something simpler with the Ternary Operator. I left it be for the time since I wanted to only talk about one concept at a time. Now that there is time, here it goes.

Ternary Operators

I have talked briefly about ternary operators before. They work basically like this.

//(test ? value if true : value if false)

//Usually used like this
var someVar = (10 % 2) == 0 ? "Even" : "Odd";

Thoughts

That is the pattern you almost always see. So I looked at the code in the last post realized, if I don’t use it in an assignment statement it’s really close to if / else. So the I took it one step further. If not assigning a value the result from the “value if true” and “value if false” statements don’t matter either.

Result

//The Original
_.reduce(
    list,
    function(output, name){
        var lCase = name[0].toLowerCase();
        
        if(output[lCase])
            output[lCase].push(name);
        else
            output[lCase] = [name];
            
        return output;
    },
    {}
);

//Could be rewritten to
 _.reduce(
    list,
    function(output, name){
        var lCase = name[0].toLowerCase();    
        
        output[lCase] ? output[lCase].push(name) : output[lCase] = [name];
        
        return output;
    },
    {}
);

It’s a narrow call on which one is more readable or justifying the revision by it being fewer lines. However I think it’s was a good though process to realise false constraints in the use of the ternary operator and find a application for it where with out those old constraints.

Grouping Items in a List Using Underscore and Reduce

List comprehension functions make solving problems with groups or lists much easier. The two most basic of the functions are Map and Reduce. From these two you can build any other operation you want. Luckily, most times you don’t have to and functions that sort or group will already exist.

A word on Underscore ‘_’

Underscore is a library for JavaScript that provides these basic list comprehension function that are native to most other functional languages. It can be used in a functional sense where you call a reduce, filter, find, etc and pass in the grouping or list you want to process. Underscore also extends the base JavaScript objects so you can use a syntax that may feel more natural to people who are used to object oriented languages. Other features of the library include tests or base object types and even a basic templating system which though really nice are not related to the rest of this post.

How about Map and Reduce

So back to the two basic functions that I mentioned earlier. Map is a function that will apply an operation to every element in a set, this can be a list of values or a collection of key value pairs. Imagine it like a station on a assembly line where it paints each part that comes down the line. Reduce is different in that it takes a collection and will return a single value. This is useful when you have a list and you want to find the largest number, it’s sum, or to test if a value exists in the collection. Reduce takes the first element, does something with it and then takes the result and looks at the next element. Think about that when computing the sum. You take one value add it to your total then take your new total and look at the next value, over and over, till you are done. There is one caveat with Reduce that need to be mentioned though, and, it’s that is it can return a collection as it’s one result.

To Group By Reduce

So Working with Reduce for fun I wanted to break a list into groups. For the record Underscore has a function that will do this .groupBy() and Reduce is supported in JavaScript in most of the Modern Browsers without needing Underscore. For this that doesn’t matter, cause, is for fun. :)

Sort Name by First Letter

For this example we are going to work with a list of names. Our goal will be to take those names and group them by the first letter in the name.

var list = 
    ["Dan", "Wayne", "Steph",  "Marc", "Duchess",
     "Deric", "Crystal", "Alex", "Wesley", "Dort"];

There are two ways we can use Underscore to reduce. We could just call .reduce() on our list since Underscore extends all our lists with its extra features. The other way is to call it from the library its self.

//Underscore extends all lists
//(Now a standard list function in modern browsers / html5)
list.reduce();

//Or on the Underscore object
_.reduce();

When calling reduce from the Underscore object we need to pass the function three parameters. The list to work on, the function to perform on each element, and the starting value for the result. The last param seeds your working function, after the first iteration that value will be the functions result. You can see this in the exampel from the underscore documentation.

//The result will be 6
_.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);

Now like I said above the function can return a list instead of a single value. For that matter it can return a hash. Now when that’s the case your seed should be the same type. What our reduce function will do is to check a hash for a key that’s the first letter of the current item. If it exists it will append it to that key, other wise it will create a new key with our item as the first value in a list. This will then produce a sorted set of names.

_.reduce(
//Our input list
    list,
//The function is called on each item in the list
//The first parameter is the value the function returned
//    for the previous item
    function(output, name){
    
        var lCase = name[0].toLowerCase();
        
        if(output[lCase]) //if lCase is a key
            output[lCase].push(name); //Add name to its list
        else
            output[lCase] = [name]; // Else add a key
            
        return output;
    },
//The seed for the first time the function is called
    {}
);
/* Returns
Object {
    a: Array[1]
    c: Array[1]
    d: Array[4]
    m: Array[1]
    s: Array[1]
    w: Array[2]
}
*/

You can see quickly that how useful this function can be. I’m not going to go back in to Map / Reduce but the reduce concept is a good tool to have when trying to solve problems. Furthermore Underscore is a good tool kit to have when your solution involves working with collections in JavaScript.

Using jQuery to Select the Last Node in a Tree

I worked on some code to show the classes that were being used on some div’s for a presentation. I wanted to be able to have the text of the class attribute show in the final container to give an idea of how the layout ended up looking and why it looked that way.

This is basically a problem of finding all the last nodes in every branch of a tree. The div’s in my case were not all the same depth from the top container

<div id="top">
    <div>
        <div></div>
        <div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
    <div>
        <div>
            <div></div>
            <div></div>
        </div>
        <div>
            <div>
                <div></div>
                <div></div>
            </div>
            <div></div>
        </div>
        <div></div>
    </div>
</div>

The way the code works is you recursively call a function that looks at all the children nodes of a node. Then you pass the children to the same function. You check to see if the node you are on has no more children and when that’s true you know you have reached the bottom of a branch in your markup tree. In my example I was using jQuery.children() but the base DOM has a similar ChildNodes function.

function ShowLowestDivStyle(parent) {
    var children = parent.children();

    if (children.length > 0) {
        children.each(function (index) {
            ShowLowestDivStyle($(children[index]));
        });
    }
    else {
        //This branch lets us use the last node
        parent.text(parent.attr('class'));
    }
}

However afterward I wanted to see if I could do the same thing with a closed from solution. My idea is to create a loop where each time we take a list of current nodes and check if they have children. If not we perform some sort of action on them. Else we get rid of our current node list and then promote our list of children to current nodes. This loop would walk down a tree one level of depth at a time.

function WorkingWithChildren(rootNode){
    var depth = 0;
    var currentNodes = $();
    
    currentNodes = rootNode.children('div');
    
    //Find all the end nodes in each branch
    while (currentNodes.length > 0) {
        //Get the next set of child nodes
        var nextNodes = currentNodes.children('div');
        
        //Perform actions on childless nodes
        currentNodes.each(function () {
            //Convert DOM node to jQuery node
            var jNode = $(this);
            if(jNode.children('div').length == 0){
                jNode.text(depth);
                jNode.attr('style', 'margin-left:' + depth + '0px;');
            }
        });
        
        //Update the list of current nodes
        currentNodes = nextNodes;
        depth++;
    }
}

If you run the script you should see each div gets indented by its level of depth and contains its level in the tree.

Looking at JavaScript Hash as a Case Alternitive

I had to do a mapping today and used the hash properties of objects in JavaScript to take care of it.

function a(key) {
    var myHash = {
        'valueOne':'mapedToA',
        'valueTwo':'mapedToB',
        'valueThree':'mapedToC',
    };

    return myHash[key];
}

Later on someone asked me about a similar issue they were trying to solve in their own code and I noticed they were using a case statement for the same type of thing.

function b(key) {
    var retVal = '';
    switch(key){
        case 'valueOne':
            retVal = 'mapedToA';
            break;
        case 'valueTwo':
            retVal =  'mapedToB';
            break;
        case 'valueThree':
            retVal =  'mapedToC';
            break;
        default:
            retVal = undefined;
            break;
    }
    
    return retVal;
}

Now, of course, I like my code better. However in this case the hash is cleaner. Seeing my hash in place of a case statement got me thinking of the switch / case pattern. In this example the hash and the case are interchangeable. So I started thinking of how in JavaScript with functions as objects, a hash could perform in the same way as the a switch / case.

Look at this case pattern:

function c(key) {
    switch(key){
        case 'valueOne':
            //do some work because it valueOne
            break;
        case 'valueTwo':
            //do some other work because it valueTwo
            break;
        default:
            //Cover our corner cases
            break;
    }
    
    return retVal;
}

Using lambdas we could do something similar with a hash:

function d(key) {
    var myHash = {
        'valueOne': function {
            //do some work because it valueOne
        },
        'valueTwo': function {
            //do some work because it valueTwo
        }
    };

    myHash[key]();
}

Now though initially when I had the idea it was quite exciting. In implementation it ends up having very similar layout and syntax to the case statement. The additional thing to notice is that when using the hash there is no default action if the value is not in the hash. When passing in a value not in our hash, an exception is thrown that the function with the name of the missing value is not defined. However it’s not much code to take care of that issue as well.

function e(key) {
    var myHash = {
        'valueOne': function() {
            //do some work because it valueOne
            alert('mapedToA');
        },
        'valueTwo': function() {
            //do some work because it valueOne
            alert('mapedToB');
        }
    };

    myHash.hasOwnProperty(key) ?
        myHash[key](): //Have key, carry on
        (function() {  //Else cover our bums
            //Cover the corner case
        })();
}

The fix is to check if the object has that property then we can execute an alternative function to cover that case. Could this have been done with an if / else instead of an ternary statement. Yeah, but the point of this exercise was to experiment with the application of functions as objects. So as soon as we define it we execute it.

With this pattern we ‘could’ use the hash in place of the case. By now we can see that the syntax of a case is much more appropriate and concise for anything beyond a simple mapping. It’s things like this that I like to explore and be creative with in JavaScript.

string.Format() in JavaScript

I love the string.format pattern in .net. It can clean up strings in your code that would otherwise be horrible to maintain. When programming in JavaScript I have often wished for the same function. This is actually fairly easily by just modifying the prototype for the string object. Prototype? Modify object? No really, it’s quite easy. The string.Format() I created for a personal project is quite simple. It could also be extended to support more of the string.Format() features by modifying the regex and adding switching code. Let’s not get ahead of our selves though. I’ll save that for another post. Here is the code I wrote:

String.prototype.format = function () {
    var formatted = this;
    for (var i = 0; i < arguments.length; i++) {
        formatted = formatted.replace(
            RegExp("\{" + i + "\}", 'g'), arguments[i]);
    }
    return formatted;
};

I will break down what is happening in the code starting with the prototype. The prototype in JavaScript is the object that all objects of that class inherit from. By extending it we add that extension to all of those objects. Here we take String reference its prototype and create a method on it. Format is just a member of the object. It is then assigned a reference to the function we define.

String.prototype.format = function () { };

The guts of the function are fairly simple. We replace any place holders with parameters that have the same number value as the position of the parameter in the arguments.

String.prototype.format = function () {
    //Copy this, the string, to a modifiable var
    var formatted = this;

    //For each argument search for place holder for it
    for (var i = 0; i < arguments.length; i++) {
        formatted = formatted.replace(

            //If a place holder exists, replace with the value
            RegExp("\{" + i + "\}", 'g'), arguments[i]);
    }
    return formatted;
};

That’s it in a nut shell.