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