Knockout.Validation and requirejs

Requirejs is a “javascript file and module loader” which allows us to asynchronously load javascript files as and when they are required. This is a massive bonus if you have a large javascript based web application because it means that you don’t need to worry about loading the files either on app start, or remember to load the files on the view that requires the files. You can use require to take care of this.

Recently Knockout.Validation was updated to better support AMD loading to allow it to be easily integrated with requirejs and a variety of other AMD javascript libraries, which rather conveniently all use a very similar syntax. But because knockout validation has a dependency on knockout, part of the require definition in the require function call in knockout validation has a hardcoded knockout reference, which means that knockout validation expects that the knockout module is called “knockout”.

This isn’t really a problem, unless you’re adding knockout to an existing project where you’ve called the knockout module something else (says ko) in the requirejs config. Since the config allows you to call modules whatever you want it seems a little strange that knockout validation would insist that you call the module knockout, it would’ve be fairly trivial to make the module name a configurable item.

Requirejs does provide a way round this in the configuration, in the form of the map configuration property. The main aim of map is to allow mapping different version of a library to the same module name in a specific context. For example if you have a module that relies on a specific older version of jQuery you can map the jquery module definition to the specific version for that module, while allowing all other modules within your application to use the newer version jquery, all without the need for any of the modules to worry about specifically having to reference the correct version of jquery. As a result of this it means we can map specific module names to other existing modules.

Here’s the config for knockout without the mapping:


require.config({
    path: {
        'ko': '/path/to/knockout'
    }
});

I’ve defined knockout as “ko” because it’s fewer characters to type. Anyway here’s my config to get knockout validation working and to make sure it loads knockout correctly when it requires it:


require.config({
    path: {
        'ko': '/path/to/knockout',
        'ko.validation': '/path/to/knockout/validation'
    },
    shim: {
        'ko.validation': ['ko']
    },
    map: {
        'ko.validation': {
            'knockout': 'ko'
        }
    }
});

Now every time knockout validation attempts to load the knockout module, require will know which module to load.

Neat little ko.observableArray trick

Knockout’s observable arrays are a great way of holding an array of data for tables, and lists and check boxes. But manipulating these array can potentially result in a lot of knockout subscriptions being fired, and can result in a load on the UI. Imagine the following simple code:

var array = ko.observableArray([]);
for(var i=0; i<100; i++) {
    array.push(i);
}

What will happen in this instance is that for each and every iteration the knockout bindings will get updated. This means that we will end up with 100 updates the bindings. Now imagine that as well as the UI binding you have a separate subscription to the knockout observable using array.subscribe(function(value) { });. This will mean that over each iteration 2 separate subscriptions are being called.

This may be alright, but it may also put undue strain on the app. Consider this alternative:

var array = ko.observableArray([]);
for (var i=0; i<100; i++) {
    array().push(i);
}
array.notifySubscribers(array());

What will happen now is that instead of firing 100 subscriptions, it will just notify the subscribers once. It should be noted that by doing this knockout will be unwrapping the observable 100 times instead, which it would have too do anyway, we’re just deferring the call to notify subscribers until after we’ve updated the array. Another alternative is:

var array = ko.observableArray([]);
var tempArray = ko.utils.unwrapObservable(array);
for (var i=0; i<100; i++) {
    tempArray.push(i);
}
array(tempArray);

This will basically have the same effect, but it does require an additional variable. While my examples aren’t very complicated, when there’s a lot of data in the arrays this really will start to make a difference. It will also mean that the UI will only be updated once all the data has been added to the array. Incidentally the same will work for pop/shift/unshift/splice/slice too.

Just as an aside knockout doesn’t always know when elements within the array have been updated (unless you use splice) so array.notifySubscribers(array()) will allow you to notify the arrays subscribers of the updated values.

Validating custom bindings with ko.validation

Knockout is a javascript library that allows simplifying dynamic javacript UIs by applying the MVVM pattern. The joy of knockout is that it really does make it easy to create dynamic UIs, with a simple binding syntax, and with the option of adding new custom bindings.

Knockout validation is a validation extension to Knockout which allows attaching validation rules to the view model.

The problem with knockout validation is that it requires a little work to get it working with custom bindings. By default knockout validation only works with the “value” and “checked” knockout bindings, which means there’s a little work involved in getting custom bindings to work with knockout validation. Fortunately knockout validation exposes the “makeBindingHandlerValidatable” which does just what it says on the tin.

In order to enable validation on a custom knockout binding first the binding needs to be registered with knockout, and then simple call “ko.validation.makeBindingHandlerValidatable(‘bindingName’)”.

I found the simplest way to deal with this is to do something like the following:

function registerCustomBindingValidation() {
  var args = Array.prototype.slice.call(arguments, 0);
  for ( var i = 0; i < args.length; i++ ) {
    ko.validation.makeBindingHandlerValidatable(args[i]);
  }
}

Then all we need to do is call the following once all the custom bindings have been registered with knockout:
registerCustomBindingValidation('customBinding1', 'customBinding2');
This will enable us to use both built in and custom validation rules on our custom binding.

Gradually moving to the cloud

I’ve been experimenting with cloud services for a while in conjunction with desktop software and I’ve not been impressed, mostly because the desktop counterparts have generally been more capable.

I didn’t really get what the big deal was until I had a catastrophic OS failure. After reinstalling the OS and all the applications I went about restoring files from backup. The moment cloud computing really clicked for me was when I was restoring my documents and realised that I actually didn’t need to restore anything because everything was just there. So I Left my documents on Google, and I started looking at what other services I can use to store my files on. Sure there are services like DropBox and SkyDrive that would left me sync files, but I’m looking for something that doesn’t have the initial sync hit.

So I checked out Google Music and Picasa, both of which allow me to sync my files up and access them anywhere from either a “traditional” desktop/laptop computer or from my phone and tablet meaning that I can access my files anywhere with an internet connection.

So now everything I want or need is just available wherever and whenever I want.

And this is the joy of the cloud and the point of the cloud! Whenever I need to access my files, regardless of which file or file type all I need is an internet connection, whether that connection is via a phone, laptop, or tablet. And it doesn’t matter whether I’m sat at home, at work, in a cafe or somewhere completely different all I need is an internet connection, and if there isn’t one available then well there’s always offline functionality which is built into most applications, so I’ll just sync the files I think I’ll need and then off I go.

And of course if all else fails I still have the offline counterparts that can be used, although I’m finding myself using them less and less!

With the increased use of phones, tablets and even laptops with built in 3G it’s perfectly possible to pretty much replace all offline applications with very capable web alternatives. And with the web alternatives becoming more and more capable every day I can see a day when there are certain applications which only exist online.

Has Google missed a trick?

In 2008 Google release Android (after buying Android Inc. in 2005). Since then it’s become one of the most successful (if not *the* most successful) smartphone OS in the world.

In 2011 Google released Chrome OS, an operating system almost entirely based on it’s Chrome web browser. Since then it’s pretty much failed to create a market for itself!

In 2011 Motorola released the Atrix smartphone, a high end Dual-Core Android phone with a neat trick up it’s sleeve; you could attach the phone to a collection of accessories to alter the functionality available. For example there was a lapdock which basically turned the phone into a cut-down netbook type device, or a multimedia dock which allowed the device to be connected to a keyboard, mouse and monitor to use it like a “net-top” type device.

Now considering how well Android is selling, and how Chrome OS has basically failed to make any real impact, I can’t help but wonder if Google missed a trick! The “computer” style functionality of the Atrix was all handled by a customised version Linux. Considering Google already has an OS which pretty much fulfils the criteria for what Motorola wanted the Atrix to do why didn’t Google work with Mototola to bring Chrome OS to the Atrix!?

Not only that but the Canonical backed Ubuntu demo’d a proof of concept implementation of it’s operating system at CES in 2012 that could potentially work on any dual-core Android smartphone… And this wasn’t a cut down and simplified version of Ubuntu either!

So why are all these other companies doing what Google should be doing!? If Google is serious about Chrome OS then maybe it should be pushing the OS into these newly emerging and very innovative markets? Think about it… With smartphones becoming increasingly powerful why wouldn’t Google want to take the opportunity to push Chrome OS? It’s obviously technically possible, and while there’s bound to be other issues… But wouldn’t it benefit Google if when you buy your new top of the range HTC/Motorola/Samsung/Whatever phone you get Chrome OS too!?

Certainly adds a USP…

I don’t want to stinkin’ apps either!

A little while ago a friend of mine posted about apps vs. services. You can read the original post here. I recently re-read the post & this got me thinking about my own relationship and interaction with apps.

I use a Windows 7 laptop, and an Android smartphone. I have very little else in the way of gizmo’s and gadgets (mostly due to lack of funds, but also due to not needing anything else) & aside from a few staples such as Visual Studio the majority of apps & applications I use the most are those which behave most list cross-platform services. By this I mean they are a service which has a platform specific UI attached.

For example I use Google Reader to read my RSS feeds. While the app itself has multiple platform specific UI’s, the service element comes in when it comes to the way the application behaves. I can read an article on my phone, and that article gets marked as read not just on the phone, but everywhere that makes use of the service! The same applies to the other Google services I use, or Evernote, or DropBox. All the services interact with the different UI’s on the different platforms seamlessly.

The point my friend was making in his post was that each service shouldn’t needs it’s own app. I understand this, and it’s one of the reasons I chose a HTC phone – Many of the services that I use are built into the phone (sadly along with many services I don’t use!). This is rather difficult though simply because of the wide variety of services that there are out there and the wide variety of platforms which use these services. However I fundamentally believe that the service should be created first though. The service should be driver for the UI. If you have to have a platform specific app then so be it, but make sure that app is driven by a service that can be integrated into many different platforms. It’s the only way to make sure that the service you provide continues to be used, even if the app isn’t!

The mobile web vs mobile apps

Ever since Apple introduced the iPhone back in 2007, and Google’s Android operating system in 2008, there has been an increasing amount of web traffic flowing thought mobile devices. This traffic has been coming form both mobile applications designed for a very specific purpose, to the mobile web browsing, which will generally allow the user to view just about any website on the internet, in pretty much the exact styling and layout that their desktop counterparts see.

This increased mobile use has created a bit of a dilemma for developers… Do they target the mobile web, or do they build a specific application (app)?

Put simply the mobile web is a generic term for a website or web application which is specifically designed and optimised for a mobile web browser, in other words a browser that is likely to have a smaller subset of functionality than that of a desktop browser, and smaller available screen space. Although the functionality available within mobile browsers has come along massively since the early days of WAP, it still doesn’t match the functionality available on a modern desktop web browser.

By comparison an app is a “small” application, designed to run natively on a single mobile platform. Although not a new idea, what Apple’s iPhone did was to create a new way of distributing the applications to devices through an “App Store”. In years gone by, to install an app it was first necessary to find the app, and any pre-requisites that the app might have, and then “hope” that the device the app is installed on is able to actually run the app. What Apple did was make this process simpler.

This brings us back to the question of whether to target the mobile web!? Unfortunately there’s no simple answer. Ultimately the answer will depend on the use case! There are certain situations where the web is almost certainly not the right solution. For example games, which require access to the graphics capabilities of the device. On the other hand there are plenty of applications where building them in a platform specific manner doesn’t make sense. For example Wikipedia! There’s no point making multiple versions of the same application just to have presence on all platforms! Make the website available as a mobile site… One version, one code base, on site… Simple!

So ultimately it depends on the use case as to whether the you write an app or a mobile optimised website…