JSON Transform
because APIs are weird
Install Stuff
Node/Browserify
Save json-transform.js and include it in your page.
Why?
  • Because you don't like the JSON you're given
  • Because you don't like the expected response format
  • Because you end up doing this anyway, and boilerplate code is bad
An Example

So, let's say we're making a request to the GitHub API.

Our URL is "https://api.github.com/repos/knockout/knockout/issues" and we get this response:


        
Basic Schema

Now we define a Schema for our data. This serves to ensure our data is of the correct type before we try to use it and end up with errors.

We only need to specify the keys we care about. There's a lot of extra stuff that we'll just ignore from the above response.

We want to do a couple things with this data.

  • ensure our data is in the correct format
  • convert all times to Moment.js objects
var schema = Schema([{
    title: String,
    created_at: moment
}]);
            

The above specifies an array of objects; each with a title of type String, and a created_at which should be a moment object.

If we had an object that needed to be constructed with new, you can use Schema.construct(Foo) which will effectivley call new Foo(data) when we give our schema the data.

Give it Some Data

Now we can give it some data, and have it processed propperly.

$.getJSON("https://api.github.com/repos/knockout/knockout/issues", functon(data){
    var fixedData = schema.fix(data);
})

But wait... there's more!

Transforms

The above is nice, and ensures your data is in the correct format, but what if you want something a little more special?

Say, we need to get all open issues with 3 or more comments; sorted by most comments first. For this, we'll need a transform

var getInteresting = Schema.transform({
    interesting: Schema.ProxyArray("").filter(function(x){
        return x.state === "open" && x.comments >= 3;
    }).sortBy(function(x){
        // sort by comments, highest first
        return x.comments * -1;
    })
});

var fixedData = schema.fix(data, getInteresting);
            
Using The Data

Well you probably know how to use resulting JavaScript object, but here's an example rendering of it:

Basically the following is foreach item in fixedData.interesting: "{{comments}} comments on an issue created {{created_at.from(moment())}}"

on an issue created