Friday, May 4, 2012

Using JSONs Special Properties of $ref and $id

I am using the JSON.NET JSON serializer for an application that I'm building and the serializer was outputting something like this as a JSON object:
var myArray = [
    {
    "AvailableStates": [
        {
        "$id": "1",
        "CityID": "CA",
        "Name": "California"},
    {
        "$id": "2",
        "CityID": "NV",
        "Name": "Nevada"}
    ],
    "DefaultState": {
        "$ref": "1"
    }}
];





I had never seen this $ref and $id tags before, so I didn't know how to use them or what to make of it. It turns out that in order to condense the JSON object into a smaller object, it avoids rewriting an object twice if it doesn't have to. In order to accomplish this, the JSON.NET serializer will serialize these special JSON properties of $id and $ref. Every object being serialized will get an $id. If that same exact object is used again somewhere in the same JSON object, it will use a $ref property to tell you that the particular object you're looking at has already been serialized. It then gives you the $id to lookup as the value of the $ref property so that you know where to find the object being referred to.

So, that was all fine and good. I understood what they were and it made complete sense, but I didn't see how to use these special properties. So, I started reading about it to see if I could find anything helpful, but no avail, I could not find anything. I finally came across a post on StackOverflow showing how to search any object using javascript and have it return to you an array of objects that matched your search. See the function below:
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));
        } else if (i == key && obj[key] == val) {
            objects.push(obj);
        }
    }
    return objects;
}

So, I gave it a shot and it worked! Here's how to use the above function assuming a JSON array that looks like the one I have defined above in this post:
var stateName = getObjects(myArray, '$id', myArray[0].DefaultState.$ref)[0].Name;

Hopefully that helps you if you're looking for something like this.

No comments: