Where to sell DVD’s and Games

I’m in the process of trying to get rid of a lot of old Wii, DS games and DVD’s. I’ve spent a long time looking for the best value and reviews about suppliers and I figure it’s worth sharing this as there isn’t really any great guides on how best to do this.

Where can I Sell?

There are a number of options that I found for where to sell things:

However I’ve found that not all of the above are reliable – there’s seems to be few who take your items and run. I’ve personally not experienced this, but I did a number of checks on review sites and some of these sites have shockingly bad reviews. Here’s the overview of what I found across sites, plus who’d I’d trust:

Of these http://www.tradeyourstuff.co.uk/ looks way too dodgy from the reviews – so I’ve removed it from the next steps. Similarly I don’t feel confident using http://uk.webuy.com/sell/ because they have a lot of bad reviews, but they also seem to slightly active on facebook in resolving issues. I’ve emailed them directly about these negative reviews to get their views/opinions, I’ve left them in for now.

Where will I get the most money?

I had ~100 DVDs and Games to sell & I wanted to get the best price possible, so I wrote a little script that would scrape all the sites and get all the prices out for me. The best way for me to share which is best is just to show the data:

As expected it’s best to use a mixture of if you plan to sell. At the moment http://uk.webuy.com/sell//CEX is offering a lot of great best prices, however I’m not yet confident in using them. As mentioned I’ve emailed them already to get some feedback on all the negative reviews, but I still don’t know if I’d trust them.

I hope this is useful for others as it can be pretty confusing knowing who to use to get the best prices.

Simplifying Grunt Jasmine tests on an Ext.js project

Are you wanting to unit test you Ext.js code but not sure where to start? Do you feel frustrated that everytime you get a bug raised you don’t know how to apply TDD techniques to your JavaScript because it’s just “not the same kind of code” as your Java, Ruby, .Net?

Since I’ve worked with Ext.js and Sencha Touch, testing has long been an issue that I’ve fought with. Initially I did no testing other than opening the browser hitting refresh and retracing my steps. However last year I went to Full Frontal and attended Rebecca Murphy’s talk (video & slides) and workshop on how to write testable JavaScript. Since then I’ve been cranking out test, after test, after test, and it’s improved the quality of code and it’s stability drastically.

However it did take me a while to understand how to setup Jasmine for an Ext.js project, so I thought something could be done about this to make life simpler. So I created a new Grunt plugin:

grunt-sencha-jasmine

It extends the grunt-contrib-jasmine so should be compatible with all options there, but it sets up a different template which just needs to know the location of the Ext framework and also any Ext.Loader.setPath() configurations.

To help show it and other ways to use Grunt on Ext.js projects I’ve setup an example Git project for people to clone and play with:

https://github.com/mattgoldspink/grunt-extjs-example

This project comes with a nice simple Grunt file and ONE Jasmine test. If you’re going to start testing, start tiny, don’t try cover your whole code base. If you can write this one unit test, let this be it!

I hope people find this useful and please feel free to give any feedback.

Using grunt with Ext.js 4.x projects

17 March 2013 – Updated to included the new simpler syntax of 0.6.0

So I stumbled across a thread last week on the Sencha forums marked under their “Trending Threads”. It’s title:

Sencha Cmd Needs Some F*****G Coffee!!!

It’s an eye catching title! Specifically there was one post there which said:

I really would love to see someone starting a yeoman/grunt based community replacement for the Sencha CMD

Having written a POC of this at an old company I thought it right that I make a proper open source version and share it. So last week I hastily hacked up my first version and very prematurely posted it to the thread, twitter and here. It was crap, worked only on my project and was riddled with a lot of bad code and bugs (apologies if you tried it and hit problems).

Over the last few days I decided to tidy up the code, add some tests, and road test it on a few more project. I’m now happy to say that it’s working pretty solidly on Ext.js and Sencha Touch projects. So I’d like to run through the simple setup on an existing project. My choice was the Pandora MVC project that Sencha provide as their MVC walkthrough application, but the following steps should work just as well on any existing project your have.

If you get stuck or have feedback please leave a comment below.

Getting started on an existing project

I’m assuming you have node.js installed, if not grab a copy from http://nodejs.org/

First thing we need to do is add a package.json file to your project which can be done by running the following on the command line:

$ cd project/root/src/dir
$ npm init

This will ask a few questions about the project name, version, test commands, etc. For the ones where you know the data fill it in, for the others just hit enter and accept the defaults – they can always be changed later.

Next up you need to get the latest version of Grunt. To do this run the following:

$ npm uninstall -g grunt
$ npm install -g grunt-cli
$ npm install grunt --save-dev

You may need to run the first two as root, depending on your OS and previous installs
This should add grunt locally to your project. Running grunt should give:

$ grunt
A valid Gruntfile could not be found. Please see the getting started guide for
more information on how to configure grunt: http://gruntjs.com/getting-started
Fatal error: Unable to find Gruntfile.

Like Ant, make, etc they all need a file which defines some tasks to run. For grunt this file should be called Gruntfile.js and be in your project root. Here’s a simple one to get started with:

module.exports = function(grunt) {

    grunt.initConfig({
        
    });

    grunt.registerTask('default', []);

};

Hopefully if you run grunt again with the above in a file called Gruntfile.js you should see:

$ grunt

Done, without errors.

Adding the sencha_dependencies task

To add the sencha_dependencies task to your project you need to do two things. First add it as a dependency via NPM:

$ npm install grunt-sencha-dependencies --save-dev

And then we need to add it to our Gruntfile.js

module.exports = function(grunt) {

    grunt.initConfig({
        sencha_dependencies: {
          app: {
            options : {
              appFile: 'app/app.js',
              pageToProcess: 'index.html'
            }
          }
        }
    });

    grunt.loadNpmTasks('grunt-sencha-dependencies');

    grunt.registerTask('default', ['sencha_dependencies:app']);

};

For your project you’ll need to tweak the following:

  • appFile – This should be the relative path of the file containing your call to Ext.application from your html file
  • pageToProcess – This should be the name of the html file which we’ll use to run your app in headlessly and figure out what files get loaded and in what order you need them in production
  • pageRoot – By default the task assumes your html pages live in the root of your project. If thats not the case and they live under some subdirectory, then you should set this property to be your subdirectory

With the file now updated with the above try running:

$ grunt
Running "sencha_dependencies:app" (sencha_dependencies) task
Processing Sencha app file index.html...
>> Success! 230 files added to property sencha_dependencies_app

Done, without errors.

This tells you that it found 230 files which your app requires and it has now written it to a new global property called sencha_dependencies_app

If you wanted to see what files it found then you can pass in the --verbose flag and you should see something like:

$ grunt --verbose
<snip>
>> Success! 225 files added to property sencha_dependencies_app
Files are:
    ../libs/ext-4.1.1a/ext-debug.js
    ../libs/ext-4.1.1a/src/util/Observable.js
    ../libs/ext-4.1.1a/src/app/Controller.js
    ../libs/ext-4.1.1a/src/util/Filter.js
    ../libs/ext-4.1.1a/src/util/AbstractMixedCollection.js
    ../libs/ext-4.1.1a/src/util/Sorter.js
    ../libs/ext-4.1.1a/src/util/Sortable.js
    ../libs/ext-4.1.1a/src/util/MixedCollection.js
    ../libs/ext-4.1.1a/src/data/proxy/Proxy.js
    ../libs/ext-4.1.1a/src/data/Operation.js
<snip>
    ../libs/ext-4.1.1a/src/data/reader/Array.js
    ../libs/ext-4.1.1a/src/data/ArrayStore.js
    ../libs/ext-4.1.1a/src/data/Batch.js
    app/app.js

Done, without errors.

Using this with our tasks to create output files

On it’s own the above isn’t all that useful, but we can use the output of the task and pass it on to any other grunt task we want now. I think the most obvious example is wanting to concatenate and minify the code, in addition let’s also generate source maps to help with debugging in chrome. For this we need another task:

$ npm install grunt-contrib-uglify --save-dev

And in our Gruntfile.js

module.exports = function(grunt) {

    grunt.initConfig({
        sencha_dependencies: {
          app: {
            options : {
              appFile: 'app/app.js',
              pageToProcess: 'index.html'
            }
          }
        },
        uglify: {
          app: {
            options: {
              sourceMap: 'build/source-map.js'
            },
            files: {
              'build/app.min.js': ['<%= sencha_dependencies_app %>']
            }
          }
        }
    });
    
    
    grunt.loadNpmTasks('grunt-sencha-dependencies');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    grunt.registerTask('default', ['sencha_dependencies:app', 'uglify:app]);

};

Now if you run grunt, you’ll see:

$ grunt
Running "sencha_dependencies:app" (sencha_dependencies) task
Processing Sencha app file index.html...
>> Success! 230 files added to property sencha_dependencies_app

Running "uglify:app" (uglify) task
Source Map "build/source-map.js" created.
File "build/app.min.js" created.
Uncompressed size: 3488667 bytes.
Compressed size: 262655 bytes gzipped (890454 bytes minified).

Done, without errors.

The uglify task uses the files output from the sencha_dependencies task via the property it created:

<%= sencha_dependencies_app %>

This is special templating syntax which means the value in the property won’t be resolved until it’s needed. After that we can see uglify created a source-map.js which will work with debuggers that support them (chrome and some versions of firebug), and finally it concated and minifed all our files into dest/app.min.js

Using the minified file in our production application

Now we have a minified set of all the files we should make sure it gets used when we go live. I’ve seen teams in the past create an index-development.html and an index-production.html. This is one option, but grunt supports a copy tasks which can do any replacement we want, so let’s keep one index.html and assume we want to update it into our build output directory.

$ npm install grunt-contrib-copy --save-dev

Our grunt task will look like:

<snip>
    grunt.initConfig({
        <snip>
        copy: {
          app: {
            files: [
              {expand: true, src: ['resources/css/ext-all.css'], dest: 'build/', cwd: '../libs/ext-4.1.1a/',},
              {expand: true, src: ['resources/themes/images/**'], dest: 'build/', cwd: '../libs/ext-4.1.1a/',},
              {src: ['index.html'], dest: 'build/'}
            ],
            options: {
              processContent: function(content, filePath) {
                // process only the index.html content
                if (/index.html/.test(filePath)) {
                  // remove the ext script
                  content = content.replace(/<script.*ext.js"><\/script>/, '');
                  // now update the css location
                  content = content.replace(/\.\.\/libs\/ext-4.1.1a\//, '');
                  // now change our app.js to app.min.js
                  content = content.replace(/app\/app.js/, 'app.min.js');
                }
                return content;
              }
            }
          }
        }
    });

    grunt.loadNpmTasks('grunt-sencha-dependencies');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-copy');

    grunt.registerTask('default', ['sencha_dependencies:app', 'uglify:app', 'copy:app']);

};

This seems a little bit complicated but let me break it down:

  files: [
    {expand: true, src: ['resources/css/ext-all.css'], dest: 'build/', cwd: '../libs/ext-4.1.1a/',},
    {expand: true, src: ['resources/themes/images/**'], dest: 'build/', cwd: '../libs/ext-4.1.1a/',},
    {src: ['index.html'], dest: 'build/'}
  ]

The above will move the CSS and image files over to our build directory, and in our addition it will move our index.html over to the build directory.

  options: {
    processContent: function(content, filePath) {
      // process only the index.html content
      if (/index.html/.test(filePath)) {
        // remove the ext script
        content = content.replace(/<script.*ext.js"><\/script>/, '');
        // now change our app.js to app.min.js
        content = content.replace(/app\/app.js/, 'app.min.js');
        // now update the css location
        content = content.replace(/\.\.\/libs\/ext-4.1.1a\//, '');
      }
      return content;
    }
  }

This function is a hook the task provides to do… well pretty much anything! In my case I want to only process the index.html file and all I want to do is:

  • remove the reference to the ext.js library JavaScript file (it’s now in a minified file)
  • swap the app.js with our new minified app.min.j
  • and also update the url location of our css file to point to our build version

That’s it… this grunt file now does pretty much want any basic app needs.

More information

This is just a small walkthrough that will hopefully get people up and running with grunt on Ext.js projects. If you do have questions on the above please leave a comment below, or if you find a bug in the grunt-sencha-dependencies task please file an issue over at https://github.com/mattgoldspink/grunt-sencha-dependencies. Similarly, if there’s features you think would be useful then please let me know (though bear in mind I want to keep this task simple and just deal with dependencies).

In addition if you want to see a fuller example Grunt file on a project please take a look at the Pandora MVC example in the project – https://github.com/mattgoldspink/grunt-sencha-dependencies/tree/master/test/integration/pandora-ext-4.1.1a

Using travis-ci with grunt 0.4.x

Update: 26/03/2013 Tim in the comments points out that if you add grunt-cli to your dev-dependencies in your package.json that will also achieve the same solution. I’d recommend his solution here instead of the below.

I thought I’d post a quick set of tips on how to setup http://travis-ci.org on a grunt plugin project as I’d spent a while trying to find the answer.

My problem was that when I followed the travis guide to setup a node.js project all it told me I needed in my .travis.yml was:

language: node_js
node_js:
  - "0.8"

However I kept getting failing builds which said:

> grunt test

sh: 1: grunt: not found
npm ERR! Test failed.  See above for more details.
npm ERR! not ok code 0

After a bit of digging around in some other projects it turns out you need one extra thing for a Grunt 0.4.x project to work:

language: node_js
node_js:
  - "0.8"
before_script:
  - npm install -g grunt-cli

After adding that travis was able to find grunt and I was back to green.

Feel free to look at https://github.com/mattgoldspink/grunt-sencha-dependencies for a working build setup.

Fed up Sencha Cmd? Want to use Grunt with Ext.js and Sencha Touch?

Are you fed up with figuring out all the bazillion commands in Sencha CMD? Do you just want to concat and minify your app without figuring out what the heck Sencha Cmd is asking you to do?

Imagine if you could just use a tool like grunt, have it figure out the app dependencies correctly and allow you to use any other grunt plugin.

I introduce my very basic grunt plugin: https://npmjs.org/package/grunt-sencha-dependencies

It just does one thing, given a js file with an Ext.application in it, what are all the other is files it needs in order to run.

It likely has bugs, and will probably need more features, but for now it does the job. So please give it a go and give me some feedback on what else you think it needs.

https://npmjs.org/package/grunt-sencha-dependencies

Update 10/02/2013 – See the follow up post Using grunt with Ext.js 4.x projects for a detailed example of this in use.

Ext.js – Cancel a load on an Ext.data.Store

Have you ever wanted to cancel a load you initiated on an Ext.js Store? Unfortunately Ext.js doesn’t provide this functionality out of the box, but the below patches provide a way of doing this.

By default the Ext.data.Store.load() call would return itself, but in the below code I changed it to return an Ext.data.Operation which I also added a new cancel() function on. To me it’s more useful to get the Operation back because I can also check the status of the load – See the Ext.data.Operation for other methods: http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.Operation

Why would I want this?

  • If you server takes a long time to load data (maybe they’re on a slow 3G connection) and the user wishes to stop the request
  • Your user misconfigures some properties in a form which setup the query with which the store loads it’s data. They may wish to change them and reload the store. This would allow the AJAX request to be aborted and the new load fired
  • Perhaps you have a large single page app and your user switches tabs and therefore there is no point in continuing with the request

There’s probably more use cases, but these are the ones I’ve come across personally.

How do I include this?

Copy the below into new files and put them in your project – I’d recommend creating the directory structure to match the names:

MG/data/OperationPatch.js

Ext.define('MG.data.OperationPatch', {
    override: 'Ext.data.Operation',
    request: null,

    setRequest: function(request) {
        this.request = request;
    },
    /**
     * Cancels the active operation
     */
    cancel: function() {
        if (this.request !== null) {
            Ext.Ajax.abort(this.request);
        }
    }
});

MG/data/AbstractStorePatch.js

Ext.define('MG.data.AbstractStorePatch', {
    override: 'Ext.data.AbstractStore',

    load: function(options) {
        var me = this,
            operation,
            request;
 
        options = options || {};
 
        options.action = options.action || 'read';
        options.filters = options.filters || me.filters.items;
        options.sorters = options.sorters || me.getSorters();
 
        operation = new Ext.data.Operation(options);
 
        if (me.fireEvent('beforeload', me, operation) !== false) {
            me.loading = true;
            request = me.proxy.read(operation, me.onProxyLoad, me);
            if (!Ext.isEmpty(request)) {
                operation.setRequest(request);
            }
        }
 
        return operation;
    }
});

Then you’ll need to configure your app to load them on startup. I usually add the following at the top of the same file as my Ext.application definition

Ext.Loader.setPath('MG', './MG'); // tweak this to be where you put the files
Ext.application({
    name: 'MyApp',
    requires: [
        'MG.data.OperationPatch',
        'MG.data.AbstractStorePatch'
    ],
    ... // rest of your Ext.application definition
});

Using the new api in your app

To cancel a request you’d simply do:

var operation = myStore.load();
...
operation.cancel();

That’s all there is to it!

Licensing

For those that need a license to use stuff, the above are released under the MIT Open Source License.

Simplifying view code in large Ext.js and Sencha apps

Do you ever feel like your view code in Ext.js is getting out of control? Do you end up copying and pasting button configs across multiple views?

Imagine if you could control all your component config in fewer places, make it easier to share config, test components and update them.

I’d like to introduce the factory pattern as a simple, but effective, solution to this.

View config explosion – A little background

When I built my first Ext.JS application I found myself focussing on what screens I needed to implement, writing classes for each view and then wiring them together. This seemed natural!

Then our design team decided to change 90% of the toolbars in the application.

“Well I’ll add a custom class to the toolbar and apply it to all that need it”.

Soon I was creating custom classes for every component and throwing them throughout all my views.

I started looking at the explosion of JSON config and began thinking “I know no longer know what bits are relevant to what in the actual view”

A few years later a colleague showed me his simple yet effective way of dealing with this – the Factory Pattern – thanks Ian!

The Factory Pattern

For those not familiar with the factory pattern, the idea is that you have a class whose sole purpose is to produce one thing. Think of a car factory – it’s purpose is to produce cars, it might produce variations in the colour or engine, but at the end of the day it will roll out cars.

A factory in programming is the same – for example an Ext.button.Button factory class’s sole purpose would be to produce buttons – maybe the buttons have different colours or text, but it just produces buttons.

Refocusing our application design

In order to benefit from the factory pattern I had to change my perspective – no longer did I just focus on what views my application needed, but I had to look hard at what common components each view used.

In fact the designer on the project created a PDF which showed all the components broken out from their views and scattered across a giant canvas. This made it much easier to see what was being used and the variations on it.

If you have a ux or design team I’d recommend getting them to create an image with just the components in it.

Creating our first factory

So now with an idea of the kinds of components you need, let’s create a Button factory – to keep things simple my hypothetical app will have only 2 types of button:

  1. a green “confirm” style button:
  2. a red “cancel” style button:

Styles for the colours will be driven by CSS, so they just need CSS classes to distinguish their type in the DOM:

Ext.define("MyApp.view.factories.ButtonFactory", {
    makeOkStyleButton: function(text, clickHandler) {
      return new Ext.button.Button({
        cls: "myapp-ok",
        handler: clickHandler
      });
    },

    makeCancelStyleButton: function(text, clickHandler) {
      return new Ext.button.Button({
        cls: "myapp-cancel",
        handler: clickHandler
      });
    }
  }
);

Hopefully this is pretty straight forward to understand. One question came up while writing the above:

Should the factory create new instances of the component or return the JSON config?

I’ve thought this through more and reasoned that if I returned a new instance it should improve rendering performance – this is because if you use an xtype Sencha has to look up the type and perform an Ext.create to instantiate it. From Sencha’s own developers they recognise this is slow and removed all traces of Ext.create from their own code.

Of course if you did want to get the config you could have another version of both methods which returns just the config, like:

Ext.define("MyApp.view.factories.ButtonFactory", {
    makeOkStyleButtonConfig: function(text, clickHandler) {
       return {
        xtype: "button",
        cls: "myapp-ok",
        handler: clickHandler
      };
    },

    makeOkStyleButton: function(text, clickHandler) {
      return new Ext.button.Button(
          this.makeOkStyleButtonConfig(text, clickHandler)
      );
    },
...

Using it in a view

To use this in a view it’s simply a matter of injecting an instance of the factory and invoking it – for example:

Ext.define("MyApp.view.ConfirmWindow", {
    extend: "Ext.window.Window",
    requires: [
        "MyApp.view.factories.ButtonFactory"
    ],
    ...
    initComponent: function() {
        if (!Ext.isDefined(this.buttonFactory)) {
            throw 'You must inject a buttonFactory';
        }
        this.btns = [
            this.btnFactory.makeCancelStyleButton("Cancel", this.handleCancel),
            this.btnFactory.makeOkStyleButton("OK", this.handleOk)
        ]
    },
    handleCancel: function() {
       ...
    },
    handleOk: function() {
       ...
    }
});

The nice thing here is that we’ve made a relatively isolated set of components that we can easily test.

Testing Factories in Jasmine

Here’s a simple Jasmine spec to test our ButtonFactory:

describe("Testing ButtonFactory", function() {

   beforeEach(function() {
       Ext.syncRequire("MyApp.view.factories.ButtonFactory");
   });

   it("Is loaded correctly", function() {
       // simple test to make sure it's loaded
       expect(MyApp.view.factories.ButtonFactory).not.toBe(undefined);
   });

   it("creates an ok button with my title and handler", function() {
       var factory = new MyApp.view.factories.ButtonFactory(),
           title = "Test Title",
           handler = function() {},
           okBtn = factory.makeOkStyleButton(title, handler);

        expect(okBtn.getText()).toBe(title);
        expect(okBtn.handler).toBe(handler);
        expect(okBtn.hasCls("myapp-ok")).toBe(true);
   });

   // repeat above for other functions if needed

});

That’s it – not very exciting, but it’s a start. Where this begins becoming really useful is when you have factories that produce more complex UI components. For example, a factory that produces custom pop-ups or flyovers can now easily be developed and tested in isolation and then wired into your views.

Promises in Ext.js and Sencha Touch

Do you feel like passing callbacks and setting scopes everywhere makes your code messy and difficult to follow?

Promises can make your code more readable, easier to debug and understand, and also a easier to test.

What is a promise though?

Simple promises

The idea of a promise is that you request someone to do something for you and in return they’ll give you a promise that it will be done and with which they will notify you. The simple flow looks like this:

    // get promise
    var promise = getUserDetails("matt");
    // register a listener to be notified when it's done
    promise.then(function(mattsDetails) {
        // got some data back - now we can
        // deal with it
    });

Compare this to callbacks:

    getUserDetails("matt", function(mattsDetails) {
        // got some data back - now we can
        // deal with it
    });

It’s pretty similar to promises right – so where’s this benefit I’m proposing? Well let’s look at a more complex, but realistic example of callbacks. Let’s imagine we have a backend that:

  • Gets details about the current user
  • gets tweets for that user
  • renders those tweets into the dom
  • Oh and if an error happens at any point we should pop up a message:

    getUserDetails("matt", function(mattsDetails) {
        getTweetsForUser(mattsDetails, function(tweets) {
            addTweetsToUi(tweets);
        }, function(error) {
            showUiErrorMessage(error);
        });
    }, function(error) {
        showUiErrorMessage(error);
    });

I’ve seen this kind of code a lot (I’ve written this kind of code too), but you know what, we can simplify this a bit:

    getUserDetails("matt", function(mattsDetails) {
        getTweetsForUser(mattsDetails, addTweetsToUi, showUiErrorMessage);
    }, showUiErrorMessage);

In fact I would usually pull out the functions to avoid nested function hell – it helps me understand the code better. So let’s see if this makes it easier to follow:

    function handleMattsDetails(mattsDetails) {
        getTweetsForUser(mattsDetails, addTweetsToUi, showUiErrorMessage);
    };
    getUserDetails("matt", handleMattsDetails, showUiErrorMessage);

Hmm… To me this way of passing around callbacks still feels hard to understand. It doesn’t seem easy to follow the code

The promises way

Let’s just take a look at how a promises implemented version would look:

    getUserDetails("matt")
           .then(getTweetsForUser)
           .then(addTweetsToUi, showUiErrorMessage);

Ok… this seems nice. Why is it better though? Well to me this just reads better, like a sentence:

“get user details (for) matt, then get tweets for (that) user, then add (the) tweets to (the) ui (or) show (a) ui error message”

I believe I could sit down at some code like this and understand what the code is trying to do with little cognitive effort. In addition I have only one error handler, this is quite a nice feature of promises, in that errors are propagated to the last error handler if they’ve not been handled before that.

So how does it work when writing the functions that return a promise?

The promises API in detail

Let’s investigate the then function we’ve been using:

    promise.then(successHandler, errorHandler);

The Promise object will have a then function with which you register one or two callbacks. The first callback will be invoked when the promise succeeds and will pass in any data as the arguments. The second callback is invoked when an error occurs and can be passed an object with details of the error.

When you’re writing code that uses promises there is an expectation that you will return a promise to the invoker of your function. To write an Ext.js function which returns a promise your code would look like:

    function getUserDetails(username) {
        var promise = new Promise();
        Ext.Ajax.request({
            url: "/user/details",
            params: {
                username: username
            },
            success: function(response) {
                var userDetails = Ext.decode(response.responseText);
                promise.resolve(userDetails);
            },
            failure: function(response) {
                promise.reject("Could not get user details - server response was " + response.status);
            }
        });
        return promise;
    }

The key bits here are the:

    promise.resolve(userDetails);

which will cause the successHandler registered to be called and given the userDetails object. Should our AJAX request fail we do:

    promise.reject("Could not get user details - server response was " + response.status);

This causes the errorHandler to be called with the given message.

Let’s do a comparison to the version implemented with callbacks:

    function getUserDetails(username, successHandler, errorHandler) {
        Ext.Ajax.request({
            url: "/user/details",
            params: {
                username: username
            },
            success: function(response) {
                if (Ext.isFunction(successHandler)) {
                    var userDetails = Ext.decode(response.responseText);
                    successHandler(userDetails);
                }
            },
            failure: function(response) {
                if (Ext.isFunction(errorHandler)) {
                    errorHandler("Could not get user details - server response was " + response.status);
                }
            }
        });
    }

To be honest there isn’t too much difference, but let’s list the differences that there are:

  1. Firstly we have to test for the two extra params and ensure they’re functions – technically we don’t, but it’s a good practice to do to avoid runtime exceptions being thrown.
  2. A more subtle issue occurs when an api changes – for example if you wanted to refactor and add a new parameter, let’s say userDetails were versioned on the server and we wanted to be able to pull back a specific version, if no version is given we should pull back the latest.

    In the promises implementation we can add an extra param to the end and if it’s not set assume we want the latest, the signature looks like:

            function getUserDetails(username, version) {…
    

    We know that we don’t need to update any code when we add this because all our old code just passed in the username. However in the callback version in order to maintain backwards compatibility we’d need to add the param at the end:

        function getUserDetails(username, successHandler, 
                                errorHandler, version) {
    

    Hmm… this just feels wrong, we could solve this by creating a new implementation call getUserDetailsVersioned or refactor all existing calls to pass in null before our callbacks. In the end though it feels like we’re working around a bad pattern.

One other key point is that if you want to chain your then functions then you just need to return promise’s from each of the functions. Therefore:

    getUserDetails("matt")
           .then(getTweetsForUser)
           .then(addTweetsToUi, showUiErrorMessage);

needs getUserDetails and getTweetsForUser to return a promise. However I’d suggest returning a promise from addTweetsToUi too – who knows when you may need to add a notification hook to the after render of the tweets.

Where do I get a Promises implementation from?

There are several implementations available. I personally use rsvp.js: https://github.com/tildeio/rsvp.js. However there are others out there.

What about testing? You said it was easier to test with

Yes I did… But I’m going to save that for another blog post

Hackday 2011 – London Borough Smackdown

Back on March 26th I was invited to a government hackday by Meg and her uni mates. The aim of the day was to get into groups and make use of government data to produce some application, ranging from useful tools, visualisations of data or making fun things with government data. We had 6 hours! I love a challenge :)

We decided to create to a Top Trumps game based on crime statistics in London Boroughs and so “London Borough Smackdown” was born:


http://www.mattgoldspink.co.uk/hackday2011/

And what’s more it won “Most Aesthetically Pleasing” award of the day! It’s designed for Android and Iphones, but will work on ipads and webkit browsers (chrome & webkit)

Big thanks to Meg Morigami, Andrea Jezovit and Maria Font who worked on this with me. I have no design skills what so ever, so this is more their award than anything to do with me.

My 2010 recap

Since I’ve not posted in a while I thought I would do a 2010 recap since it was quite a different year for me in a lot of ways. So here’s a run down of some of my highlights:

10. Getting DJ lessons a the Ministry of Sound and being told I have natural talent by Karl Brown! If only I did something with it… My that’s my first 2011 new years resolution.
9. Learning rock climbing with Megu. A fantastic sport and I have a whole new appreciation for how much of an art scaling cliff faces is now.
8. Trying my hand at stand up comedy. On a bit of a whim I thought I’d give it a go and had an amazing time with it, meeting lots of new people and also learning how scary things can get. If you ever want an adrenaline high, then stand up comedy is an amazing way to get it. (if you put my name in to YouTube you may find a clip of my first show)
7. Joining a new team at work. After 3 years of what can online described as hardcore java development I moved into a team to now do what can only be described as hardcore JavaScript development, but I love it and my new team mates are awesome. We have such a great time and I’ve been lucky to work on some amazing projects.
6. Learning White water kayaking (again). I joined the regents canoe club and went on the intro to White water course which again was just an awesome experience and I meta lot of fantastic people. My first kayaking related resolution for 2011 is to learn to roll which I’ll be starting in about a weeks time!
5. Learning Kung Fu at the Shaolin Temple in London. Megu finally persuaded me to try it out and I was bowled over with how hard it was, but how good I felt afterwards and also how much my fitness improved! My 2011 resolution is to go at least twice week and get at least one belt.
4. Getting an iPad for 1/2 price! On which I’m writing this now. I love a good bargain. Megu is glad I’ve finally jumped on the apple and bandwagon and I have to admit I’ve been amazed by how great it is, especially for someone who travels a lot.
3. Releasing my first open source project and getting a lot if great feedback on it. I love subsonic music player, but I’m not too happy with the UI and usability so I figured I would tackle it myself. However I’m not much of a designer and so my uber intelligent girlfriend suggested I just make it look like iTunes. I’m sure there’s issues with this legally, but I won’t make any money from it and personally I see it as an homage to Apple’s great products and also a demo of what a real web app can do.
2. Street dance lessons. Sometimes Megu can get me to do some weird, but cool stuff that I i never thought I would do. I’m glad she persuaded me to try this. I can now Krump and Wack like the best of them.
1. Horse trekking in Wales. I think this was one of the biggest highlights for me as it was such a beautiful experience, even if I did end up with really bad saddle rash! Megu and I had a fantastic time and we can’t wait to go again. She also cleverly signed us up to volunteer to create a website for a local horse riding charity for disabled people which I’m really proud of her for. It should be making an appearance in the new year.

The above were in no particular order. I hope that I can keep up with all these new hobbies in 2011 and without sounding too mushy I’d like to thank my wonderful girlfriend for making so many of the experiences last year happen and for just being so fantastic.