JasonWyatt

This blog is full of stuff, and things.

Find my resume.

permalink

Google Maps API in an AMD Module (RequireJS / Dojo)

At my day job I do a lot of work with the Google Maps JavaScript API. We’ve recently been getting more into using RequireJS for our new projects, and one of the things I originally struggled with was that I’d need to include an additional <script> tag in the markup just for Google Maps.

Until I discovered how to wrap the Google Maps API in an AMD Module:

This module can be used by both RequireJS and Dojo users.

permalink

How to correctly debounce a JavaScript function.

This function correctly debounces a function that is anticipated to be called many times with identical input in a short amount of time:

permalink

Singleton Pattern with RequireJS

Here’s a quick Gist on how to create a singleton with RequireJS.

permalink

Natural Log in JavaScript

If you need to take the natural log (a.k.a. “ln”) of a value in JavaScript, you might at first be disheartened to learn there is no such thing as Math.ln() - only Math.log(). However, if you remember way back to high school mathematics, you can use the following identity to calculate logarithms of any base via any other base:

Logb(x) = Loga(x) / Loga(b)
Since the natural log has a base of e and the basic verson of Math.log uses a base of 10, we need to do the following:
Ln(x) = Loge(x) = Log10(x) / Log10(e)
In JavaScript, this becomes:
function ln(val){
    return Math.log(val) / Math.log(Math.E);
}
We can optimize it, however, by using a built-in constant from the Math object so we don’t need to calculate Math.log(Math.E) every time we need to take the natural log of a value:
function ln(val){
    return Math.log(val) / Math.LOG10E;
}

permalink

How to kick off a TestSwarm job from jQuery…

Towards the end of last week I set up an instance of John Resig’s TestSwarm server here at TransLoc. In case you’re not familiar with it, here’s an excerpt of the description from the TestSwarm wiki at GitHub:

TestSwarm provides distributed continuous integration testing for JavaScript. It was initially created by John Resig as a tool to support the jQuery project and has since moved to become an official Mozilla Labs project.

I’ve got to admit, I’m blown away by the elegance with which TestSwarm solves such a complicated problem. Basically, you throw TestSwarm’s PHP contents onto a LAMP server, create some Cron Jobs or Post-Commit Hooks to watch your version control system, point browsers at your server, then sit back and watch the results come in.

Unfortunately, in the current version of TestSwarm there is no simple way to kick off test jobs without a cron job/hook. Apparently, there used to be a web-based form that would work, but it seems to be missing.

Below, you’ll find a really quick $.ajax() invocation that will initiate a test job on a TestSwarm server. Just make sure that the “urls” parameter contains urls with valid QUnit/DOH/etc. test modules that can be accessed by the swarm’s browsers (i.e. not filesystem urls on your development machine).

$.ajax({
    data: {
        state: "addjob",
        output: "dump",
        user: "[Your User Name]",
        auth: "[Your Authentication Key]",
        max: 5,
        job_name: '[Whatever name you want]',
        browsers: 'all',
        'suites': [
            "Suite 1",
            "Suite 2",
            "Suite 3",
            "Suite 4"
        ],
        'urls': [
            "http://url/to/test/suite/1.html",
            "http://url/to/test/suite/2.html",
            "http://url/to/test/suite/3.html",
            "http://url/to/test/suite/4.html"
        ]
    },
    url: 'http://[your testswarm location]',
    traditional: true,
    success: function(data){
        console.log(data);
    }
});

The nice thing about this little script is that it can be run from within Firebug or the Webkit developer tools in a browser that’s already pointed at your TestSwarm server (because it includes jQuery for you).

permalink

We put together a video showing time lapse of the development process behind a new feature for TransLoc.

permalink

Anonymous Classes with JavaScript and Self-Calling Functions

I was messing around with Firebug today, trying to test out a concept for event handling and I didn’t want to have to go through all the pomp and circumstance of creating a legitimate class in the firebug console so I dreamed up a way to make an anonymous class. Here’s what I came up with: (I left out the event handling stuff)

var a = new (function(name){
    this.sayHello = function(){
        console.log("Hello, ", name, "!");
    };
})("Jason");

a.sayHello();

What’s going on here? Remember that classes in JavaScript are just functions that can be called with the new keyword to instantiate a new object of the class defined by that function. (the function acts as the class’s constructor) So, we’re setting a variable, a, to a new instance of a class whose constructor is an anonymous function wrapped in parentheses to encapsulate it.

We can take this concept even further by working with our anonymous class’s prototype after we instantiate it. However, I cant really think of a practical reason to do this other than to make the code prettier, if you know - leave a comment.

var a = new (function(name){
    this.name = name;

    this.sayHello = function(){
        console.log("Hello, ", this.name, "!");
    };
})("Jason");

a.constructor.prototype.sayGoodbye = function(){
    console.log("Goodbye, ", this.name,".");
};

a.sayHello();
a.sayGoodbye();

Why do I care?

Anonymous classes can be useful for things like mock objects in the case of unit tests. Imagine that you have a unit test which checks that a static method called serialize() correctly serializes an instance of its class, MyClass to a JSON string. We don’t really want to create a new instance of the real class if we only need to check that certain attributes are correctly serialized. Check it out:

/* 
 Lots of code to describe MyClass
 */
MyClass.serialize = function(instance){
    return JSON.stringify({
        name: instance.getName(),
        longList: instance.getList()
    });
};

/*
 In another file, for our unit test...
 */
function testSerialize(){
    var data = {
        name: "Awesome object.",
        longList: [1,2,3,4]
    };

    var actualResult = MyClass.serialize(new (function(settings){
        this.getName = function(){
            return settings.name;
        }
        this.getList = function(){
            return settings.longList;
        }
    })(data));

    assertEqual(JSON.stringify(data), actualResult);
}

I realize that this probably isn’t all that novel, but it’s an example of how JavaScript is a great language for allowing programmers to be creative.

permalink [Flash 9 is required to listen to audio.]

Marv Ellis - Opus