I'm thinking this must be a common problem but can't seem to find the solution. Using JSON config files to extend a jQuery object that contains objects and arrays.
For the objects and simple properties, I want to overwrite (as extend does nicely).
For the arrays there may or may not be existing items.
Currently an array just overwrites the first elements
var sourceObj = {propterty:"change Me",anArray:[{name:"first"},{name:"second"}]},
    configJSON = '{"propterty":"New Val","anArray":[{"name":"third"}]}',
    configObj = JSON.parse(configJSON);
$.extend(true,sourceObj,configObj);
http://jsfiddle.net/PmuwV/
This returns:
{propterty:"New Val" , anArray:[{name:"third"},{name:"second"}}
Can I instead get:
{propterty:"New Val",anArray:[{name:"first"},{name:"second"},{name:"third"}]}
while ALSO allowing for updating "first" and "second" objects?
"anArray":[{"name":"second","newProp":"add newProp to second"}]
Could/should extend be modified to compare array items and extend or add based on some rule or set property value such as "name"?
Thanks for any advice or pointers.
I used this solution http://jsfiddle.net/PmuwV/2/ modified from How can I merge properties of two JavaScript objects dynamically? also from JavaScript equivalent of jQuery's extend method
requires isDOMNode() I just added in a jquery merge (yes I feel dirty too) on arrays in which duplicates will need to be cleaned up post merge. The Jquery source for extend does something very similar but i found this to be more readable.
function mergeRecursive() {
  // _mergeRecursive does the actual job with two arguments.
  var _mergeRecursive = function (dst, src) {
    if ( isDOMNode(src) || typeof src!=='object' || src===null) {
      return dst; 
    }
    for ( var p in src ) {
//my added bit here - [SB]
      if ($.isArray(src[p])){
          $.merge(dst[p],src[p]);
          var dupes = {},
               singles = [];
          $.each(  dst[p], function(i, el) {
             if ((dupes[el.name] > -1) &&  (el.name)) {
                 $.extend(singles[dupes[el.name]],el);
             }else{
                  if (el.name ){
                     dupes[el.name] = i;
                  }
                 singles.push(el);
             }
         });
         dst[p] = singles;
         }
         continue;        
      }
//the rest is original - [SB]
      if( !src.hasOwnProperty(p) ) continue;
      if ( src[p]===undefined ) continue;
      if ( typeof src[p]!=='object' || src[p]===null) {
        dst[p] = src[p];
      } else if ( typeof dst[p]!=='object' || dst[p]===null ) {
        dst[p] = _mergeRecursive(src[p].constructor===Array ? [] : {}, src[p]); 
      } else {              
        _mergeRecursive(dst[p], src[p]);
      }
    }
    return dst;
  }
  // Loop through arguments and merge them into the first argument. 
  var out = arguments[0];
  if ( typeof out!=='object' || out===null) return out;
  for ( var i=1, il=arguments.length; i<il; i++ ) {
    _mergeRecursive(out, arguments[i]);
  }
  return out;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With