Pages

Friday, February 3, 2012

Merging JSON Objects Successfully

If you've been using JavaScript for a while you've probably come across the problem of comparing JSON objects. At first glance it doesn't seem to be very easy since {} !== {} evaluates to true. One solution would be to use JSON.stringify on the objects and you would be able to see equality.

Another problem is doing a merge of objects since $.extend() and $.merge() fall a little short. Merge is used for arrays and will put duplicate objects into the merged array. Extend doesn't do a complete recursive merge merge even with passing the parameter true for deep.

Take a look:

var obj1 = {
    data: [
        {
            id: 1,
            text: "1"
        },
        {
            id: 2,
            text: "2"
        },
        {
            id: 3,
            text: "3"
        }
    ]
};



var obj2 = {
    data: [
        {
            id: 3,
            text: "three"
        },
        {
            id: 4,
            text: "4"
        }
    ]
};

$.extend(true, obj1, obj2) yields:
//Missing {id: 1, text: "1"} and {id: 2, text: "2"}
{
  "data": [
    {
      "id": 3,
      "text": "three"
    },
    {
      "id": 4,
      "text": "4"
    },
    {
      "id": 3,
      "text": "3"
    }
  ]
}

jQuery's extend for the data array seems to be doing a merge based on position instead of comparison with obj1's objects in the same position. The options are slowly dwindling. That's why I made my own recursive function to do a deep merge. You can check out my gist and run mergeDeep(obj1, obj2) to return:

//All the data has been merged properly
{
  "data": [
    {
      "id": 1,
      "text": "1"
    },
    {
      "id": 2,
      "text": "2"
    },
    {
      "id": 3,
      "text": "3"
    },
    {
      "id": 3,
      "text": "three"
    },
    {
      "id": 4,
      "text": "4"
    }
  ]
}

No comments:

Post a Comment