.gitignore for Worklight

I have recently started maintaining a .gitignore template file for IBM Worklight Foundation on github, in a similar spirit to the standard gitignore repository. Please feel free to take a look; just copy the Worklight.gitignore file into the root of your Worklight project, and rename it to .gitignore – then you’re ready to go.

It’s unofficial, and possibly not complete/accurate, so caveat emptor – any pull requests for fixes or enhancements will be gladly received.

Transforming worklight.properties values in JNDI properties suitable for insertion into a Liberty server.xml

If you’re working with a Worklight application, you might like to exploit the fact that Worklight allows you to programmatically retrieve custom values from the worklight.properties file defined in your Worklight project. For example, you can write code like this:

function myAdapterProcedure(opt1, opt2) {
  var path = WL.Server.configuration["myadapter.path"];

  var input = {
    method: 'get',
    path: path
  }

  WL.Server.invokeHttp(input);
}

Your worklight.properties might look like:

myadapter.path=/myserver/somepath/service

This is quite useful, but becomes even more useful when combined with the fact that Worklight allows you to override the worklight.properties values with JNDI properties defined on the server. This enables you to easily automate having different values for these properties on different development environments – for example, to connect to different backend servers.

Assuming you are using WebSphere Liberty, here’s a Perl one-liner that you can use to transform a worklight.properties file into the equivalent JNDI properties definitions, suitable for inserting into the server.xml for Liberty:

cat worklight.properties.$ENVIRONMENT | grep  "^\w" | perl -p -i -e 's/((?:\w+\.)*(?:\w+.))=(.*)/<property name="$1" value="$2"\/>/g' > $TEMPFILE

$TEMPFILE will now contain your transformed properties, which will look like these:

<property name="myadapter.path" value="/myserver/somepath/service"/>

This is suitable for directly inserting into your Liberty server’s server.xml.

Where do I specify the hostname of my Worklight server?

When developing a Worklight application, there are various places the hostname of your Worklight server might need to be specified, and might end up:

  • In the mobile app itself (the .ipa, .apk etc.) – this value (prior to Worklight V6) was taken from the application-descriptor.xml file during the build of the application and determines where the app attempts to connect back to for adapter calls and so on. In versions of Worklight subsequent to V6, it is now specified instead in the <app-builder> ANT task (used for automated builds of the application) inside the worklightServerHost property.
  • In the publicWorkLightHostname, publicWorkLightProtocol, and publicWorkLightPort values inside the worklight.properties file. These values determine:
    • Where the Mobile web and desktop browser apps should connect back to.
    • How the Worklight Application Center (if used) will form RESTful URLs for its own internal use.

In all cases, these hostnames should point to the externally-resolvable address of the Worklight server (in front of any load-balancers, firewalls, proxies, etc.).

Thanks to Itay Hindy and Thomas Kw Poon for help with this tip.

Chrome Developer Tools Tricks

This post is a round-up of some of the less-known debugging tricks I’ve learnt about related to the Chrome Developer Tools window. You might know some, but hopefully there’s at least one in here which is new.

Formatting

Suppose you are reading some badly-formatted JavaScript code from a developer with no respect for formatting. Or maybe (and hopefully more likely), you are reading some code that’s been through a minification process, such as the Dojo Build System. Either way, it’s possible, from with the Sources window, to hit this button on the bottom-left:

1

That turns the mess of JavaScript into something more cleanly-formatted and readable:

2

Tracking down exceptions

Sometimes, you’re dealing with code with which you’re a little unfamiliar. For example, a page might load, but isn’t displaying correctly, and you’re not sure why. You’re suspicious that there’s an exception being thrown somewhere which might narrow down the problem, but you’re not sure where. That’s where the “Pause on exception” button comes in handy:

3

Clicking it toggles between 3 states:

  • Dark grey = Off
  • Light blue = Break on all exceptions
  • Dark purple = Break only on uncaught exceptions (ones not caught by a try/catch block)

The last state is by far the most helpful; caught exceptions aren’t usually that interesting, as they typically indicate an “expected” path in the code; uncaught exceptions, on the other hand, are normally cause for concern. This button can help you establish more quickly where code is going awry.

An Anti-Trick: Disabling Cache

Browser caching has been for a long time – and remains – the bane of a web developer’s existence. Chrome has attempted to address this issue by adding a “Disable cache” checkbox inside the Developer Tools settings window:

4

5

However, be aware that this only works whilst the Developer Tools window is open. If, like me, you are limited in screen space, you may be in the habit of closing Developer Tools when you aren’t actively debugging a site. In that case, this checkbox won’t take effect. In that case, you’ll have to rely on another method, such as manually clearing the cache.

Functional Mapping Across Object Attributes in Dojo

Recently I discovered the very useful function dojox/lang/functional.mapIn(). This allows you to functionally transform one object to another by mapping each value in the object using a callback function. It’s similar to dojo/_base/array.map() but works on objects instead.

For example, let’s define an object like this that contains some values that are integers, and others that are strings:

var x = { "A": 1, "B": "2" };

We can convert (or normalize) all of these to strings by executing the following code:

require(["dojox/lang/functional", function(functional) {
    x = functional.mapIn(x, function(value) { return value.toString(); });
});

Now, x looks like this:

{"A":"1","B":"2"}

Displaying and Styling a Read-only Dojo Tree Control

In this tutorial, we are going to be using the Dojo toolkit – a popular JavaScript tookit shipped with the IBM Feature Pack for Web 2.0 and Mobile. Specifically, we are going to be using the dijit.Tree class from the Dojo toolkit to display a simple Dojo read-only tree that can display information from a hierarchy of data. We’ll also style the tree, showing how to style different levels of the tree differently.

We’ll start out with a basic JavaScript object that contains some data we want to display. It’s hierarchical in nature – arrays inside arrays. In this example, we assume we are running an online retailer, and we want to display all the customers we have, and for each, all the orders they have made in the last month, then within those, each of the items in the order. Our object looks like this:

var customerOrderHistory = [
    {
        "name": "Fred Bloggs",
        "customerNum": 23,
        "orders": [
            {
                "orderNum": "0001",
                "items": [
                    {
                        "description": "Gone with the Wind (DVD)",
                        "itemNum": 56
                    },
                    {
                        "description": "Oxford English Dictionary",
                        "itemNum": 78
                    }
                ]
            },
            {
                "orderNum": "0002",
                "items": [
                    {
                        "description": "Whittaker's Alamanac",
                        "itemNum": 90
                    }
                ]
            }
        ]
    },
    {
        "name": "David Smith",
        "customerNum": 45,
        "orders": [
            {
                "orderNum": "0003",
                "items": [
                    {
                        "description": "King James Bible",
                        "itemNum": 112
                    }
                ]
            }
        ]
    }
];

Before we can create a Dojo Tree to display this data, we need to create a Tree Model. In our case, we’re going to use the dijit.Tree.ForestStoreModel to do this, as our tree has multiple roots (customers).

In turn, in order to create this tree model, we in turn need to get place our items into a Dojo data store (we’re going to use the dojo.data.ItemFileReadStore, as it’s well placed for handling in-memory data). To create this data store, we first need a data structure where each node and leaf in the tree has a consistent field name for its identifier (the internal representation of that node or leaf) – which must be unique across the entire tree – and a consistent field name for its label (what will be displayed on the screen for that node or leaf). Each node also needs to have a consistently named array that contains its child elements. Therefore, we need to write a data restructuring function. Our looks like this:

_restructureCustomerData = function(data) {
        var newData = dojo.map(data, dojo.hitch(this, function(customer) {
            var newCustomer = {};

            newCustomer.id = customer.customerNum;
            newCustomer.name = customer.name;

            newCustomer.children = dojo.map(customer.orders, dojo.hitch(this, function(idPrefix, order) {
		var newOrder = {};

		newOrder.id = idPrefix + "_" + order.orderNum;
		newOrder.name = order.orderNum;

		newOrder.children = dojo.map(order.items, dojo.hitch(this, function(idPrefix, item) {
		    var newItem = {};

		    newItem.id = idPrefix + "_" + item.itemNum;
		    newItem.name = item.description;

		    return newItem;
		    }, newOrder.id));

		return newOrder;
		}, newCustomer.id));

            return newCustomer;
        }));

        return newData;
    }

This will walk through the object tree of our initial data, and at each level will use the dojo.map function to create an entirely new resultant object tree, that consistently at each level uses the field names id (for the identifier) and name (for the label). Each non-leaf node also has a field called children that contains the child elements. For illustration, the resultant object looks like this:

[
    {
        "id": 23,
        "name": "Fred Bloggs",
        "children": [
            {
                "id": "23_0001",
                "name": "0001",
                "children": [
                    {
                        "id": "23_0001_56",
                        "name": "Gone with the Wind (DVD)"
                    },
                    {
                        "id": "23_0001_78",
                        "name": "Oxford English Dictionary"
                    }
                ]
            },
            {
                "id": "23_0002",
                "name": "0002",
                "children": [
                    {
                        "id": "23_0002_90",
                        "name": "Whittaker's Alamanac"
                    }
                ]
            }
        ]
    },
    {
        "id": 45,
        "name": "David Smith",
        "children": [
            {
                "id": "45_0003",
                "name": "0003",
                "children": [
                    {
                        "id": "45_0003_112",
                        "name": "King James Bible"
                    }
                ]
            }
        ]
    }
]

We can now use this object as the input to the creation of a data store:

var store = new dojo.data.ItemFileReadStore({
        data: {
            "identifier": "id",
            "label": "name",
            "items": restructuredData
        }
    });

And then in turn a store model:

var treeModel = new dijit.tree.ForestStoreModel({
        store: store,
        rootId: "root",
        rootLabel: "Customers",
        childrenAttrs: ["children"]
    });

Assuming that have an HTML div on our page with an id of “_treeHolder”, we can now create the tree and attach it to that empty div:

this._tree = new dijit.Tree({model: treeModel, showRoot: false}, dojo.byId("_treeHolder"));

The tree will now display successfully. With some items expanded, it looks like this:

Applying styles to the tree

There are many ways we can apply CSS styling to the tree. However, a category of advanced techniques involves overriding the tree class itself to add different CSS classes to different levels of the tree, therefore enabling different styles at different depths. We start out by altering the _restructureCustomerData function slightly to insert metadata about each object, specifically which CSS class we want to apply to each level in the tree:

 _restructureCustomerData = function(data) {
        var newData = dojo.map(data, dojo.hitch(this, function(customer) {
            var newCustomer = {};

            newCustomer.id = customer.customerNum;
            newCustomer.name = customer.name;
	    newCustomer.cssClass = "customer";

            newCustomer.children = dojo.map(customer.orders, dojo.hitch(this, function(idPrefix, order) {
		var newOrder = {};

		newOrder.id = idPrefix + "_" + order.orderNum;
		newOrder.name = order.orderNum;
	        newOrder.cssClass = "order";

		newOrder.children = dojo.map(order.items, dojo.hitch(this, function(idPrefix, item) {
		    var newItem = {};

		    newItem.id = idPrefix + "_" + item.itemNum;
		    newItem.name = item.description;
                    newItem.cssClass = "description";

		    return newItem;
		    }, newOrder.id));

		return newOrder;
		}, newCustomer.id));

            return newCustomer;
        }));

        return newData;
    }

We now extend the dijit.Tree class itself to create our own tree class, overriding the getRowClass() function. This allows us to assign a custom CSS class to each row, based on the data we’ve just inserted into the data store:

    dojo.declare("ibm.dijit.examples.LevelSensitiveTree", [ dijit.Tree ], {
	getRowClass: function(item, opened) {
	    if(item.id !== "root") {
		return this.model.store.getValue(item, "cssClass");
            }
	}
    });

We can then use this new tree class in the same way as the regular dijit.Tree class. The resultant tree looks like this:

In this article you have hopefully learnt some practical lessons on how to use and style Dojo trees based on raw data.

Seeing the JavaScript console when writing PhoneGap applications in Eclipse

Recently I’ve been doing some work with writing PhoneGap/Dojo Mobile applications for Android, using Eclipse as the IDE. These work just fine with the Android emulator, but it took me a while to find where I could see the output of the JavaScript console. To show it, select Window -> Show View -> Other… in Eclipse. Then select the LogCat view (under the Android section). This will show all log messages for the emulator, but it can be further filtered to show only errors from the JavaScript console. Simply click on the green cross to add a Filter, then give the filter a name and enter “Web Console” for the Log Tag. Click OK and you’ll see only errors related to the browser (including JavaScript errors).