Combine or merge JSON on node.js without jQuery
JavascriptJqueryJsonnode.jsJavascript Problem Overview
I have multiple JSON
like those
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
They are not nesting or anything like that. Just basically different fields. I need to combine them into one single JSON
in node.js like this:
{name: "John", location: "San Jose"}
I can use jQuery just fine. Here is a working example in the browser:
http://jsfiddle.net/qhoc/agp54/
But if I do this in node.js, I don't want to load jQuery (which is a bit over use, plus node.js' jQuery doesn't work on my Windows machine).
So is there a simple way to do things similar to $.extend()
without jQuery?
Javascript Solutions
Solution 1 - Javascript
Object.assign()"
You should use "There's no need to reinvent the wheel for such a simple use case of shallow merging.
> The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };
var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed
Even the folks from Node.js say so:
> _extend
was never intended to be used outside of internal NodeJS modules. The community found and used it anyway.
> It is deprecated and should not be used in new code. JavaScript comes with very similar built-in functionality through Object.assign
.
Update:
spread operator
You could use theSince version 8.6, it's possible to natively use the spread operator in Node.js. Example below:
let o1 = { a: 1 };
let o2 = { b: 2 };
let obj = { ...o1, ...o2 }; // { a: 1, b: 2 }
Object.assign
still works, though.
PS1: If you are actually interested in deep merging (in which internal object data -- in any depth -- is recursively merged), you can use packages like deepmerge, assign-deep or lodash.merge, which are pretty small and simple to use.
PS2: Keep in mind that Object.assign doesn't work with 0.X versions of Node.js. If you are working with one of those versions (you really shouldn't by now), you could use require("util")._extend
as shown in the Node.js link above -- for more details, check tobymackenzie's answer to this same question.
Solution 2 - Javascript
If using Node version >= 4, use Object.assign()
(see Ricardo Nolde's answer).
If using Node 0.x, there is the built in util._extend:
var extend = require('util')._extend
var o = extend({}, {name: "John"});
extend(o, {location: "San Jose"});
It doesn't do a deep copy and only allows two arguments at a time, but is built in. I saw this mentioned on a question about cloning objects in node: <https://stackoverflow.com/a/15040626>;.
If you're concerned about using a "private" method, you could always proxy it:
// myutil.js
exports.extend = require('util')._extend;
and replace it with your own implementation if it ever disappears. This is (approximately) their implementation:
exports.extend = function(origin, add) {
if (!add || (typeof add !== 'object' && add !== null)){
return origin;
}
var keys = Object.keys(add);
var i = keys.length;
while(i--){
origin[keys[i]] = add[keys[i]];
}
return origin;
};
Solution 3 - Javascript
Underscore's extend
is the easiest and quickest way to achieve this, like James commented.
Here's an example using underscore:
var _ = require('underscore'), // npm install underscore to install
object1 = {name: "John"},
object2 = {location: "San Jose"};
var target = _.extend(object1, object2);
object 1 will get the properties of object2 and be returned and assigned to target. You could do it like this as well, depending on whether you mind object1 being modified:
var target = {};
_.extend(target, object1, object2);
Solution 4 - Javascript
A normal loop?
function extend(target) {
var sources = [].slice.call(arguments, 1);
sources.forEach(function (source) {
for (var prop in source) {
target[prop] = source[prop];
}
});
return target;
}
var object3 = extend({}, object1, object2);
That's a basic starting point. You may want to add things like a hasOwnProperty
check, or add some logic to handle the case where multiple source objects have a property with the same identifier.
Here's a working example.
Side note: what you are referring to as "JSON" are actually normal JavaScript objects. JSON is simply a text format that shares some syntax with JavaScript.
Solution 5 - Javascript
Use merge.
$ npm install merge
Sample code:
var merge = require('merge'), // npm install -g merge
original, cloned;
console.log(
merge({ one: 'hello' }, { two: 'world' })
); // {"one": "hello", "two": "world"}
original = { x: { y: 1 } };
cloned = merge(true, original);
cloned.x.y++;
console.log(original.x.y, cloned.x.y); // 1, 2
Solution 6 - Javascript
I see that this thread is too old, but I put my answer here just in logging purposes.
> In one of the comments above you mentioned that you wanted to use > 'express' in your project which has 'connect' library in the > dependency list. Actually 'connect.utils' library contains a 'merge' > method that does the trick. So you can use the 3rd party > implementation without adding any new 3rd party libraries.
Solution 7 - Javascript
Here is simple solution, to merge JSON. I did the following.
-
Convert each of the JSON to strings using
JSON.stringify(object)
. -
Concatenate all the JSON strings using
+
operator. -
Replace the pattern
/}{/g
with","
-
Parse the result string back to JSON object
var object1 = {name: "John"}; var object2 = {location: "San Jose"}; var merged_object = JSON.parse((JSON.stringify(object1) + JSON.stringify(object2)).replace(/}{/g,","))
The resulting merged JSON will be
{name: "John", location: "San Jose"}
Solution 8 - Javascript
You can also use this lightweight npm package called absorb
It is 27 lines of code, 1kb and uses recursion to perform deep object merges.
var absorb = require('absorb');
var obj1, obj2;
obj1 = { foo: 123, bar: 456 };
obj2 = { bar: 123, key: 'value' }
absorb(obj1, obj2);
console.log(obj1); // Output: { foo: 123, bar: 123, key: 'value' }
You can also use it to make a clone or only transfer values if they don't exist in the source object, how to do this is detailed in the link provided.
Solution 9 - Javascript
It can easy be done using Object.assign() method -
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
var object3 = Object.assign(object1,object2);
console.log(object3);
now object3 is { name: 'John', location: 'San Jose' }
Solution 10 - Javascript
There is an easy way of doing it in Node.js
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
To combine/extend this we can use ...
operator in ECMA6
var object1 = {name: "John"};
var object2 = {location: "San Jose"};
var result = {
...object1,
...object2
}
console.log(result)
Solution 11 - Javascript
If you need special behaviors like nested object extension or array replacement you can use Node.js's extendify.
var extendify = require('extendify');
_.extend = extendify({
inPlace: false,
arrays : 'replace',
isDeep: true
});
obj1 = {
a:{
arr: [1,2]
},
b: 4
};
obj2 = {
a:{
arr: [3]
}
};
res = _.extend(obj1,obj2);
console.log(JSON.stringify(res)); //{'a':{'arr':[3]},'b':4}
Solution 12 - Javascript
Lodash is a another powerful tool-belt option for these sorts of utilities. See: _.merge()
(which is recursive)
var object = {
'a': [{ 'b': 2 }, { 'd': 4 }]
};
var other = {
'a': [{ 'c': 3 }, { 'e': 5 }]
};
_.merge(object, other);
// => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
Solution 13 - Javascript
Use spread operator. It is supported in Node since version 8.6
const object1 = {name: "John"};
const object2 = {location: "San Jose"};
const obj = {...object1, ...object2}
console.log(obj)
// {
// "name": "John",
// "location": "San Jose"
// }
Solution 14 - Javascript
The below code will help you to merge two JSON object which has nested objects.
function mergeJSON(source1,source2){
/*
* Properties from the Souce1 object will be copied to Source2 Object.
* Note: This method will return a new merged object, Source1 and Source2 original values will not be replaced.
* */
var mergedJSON = Object.create(source2);// Copying Source2 to a new Object
for (var attrname in source1) {
if(mergedJSON.hasOwnProperty(attrname)) {
if ( source1[attrname]!=null && source1[attrname].constructor==Object ) {
/*
* Recursive call if the property is an object,
* Iterate the object and set all properties of the inner object.
*/
mergedJSON[attrname] = zrd3.utils.mergeJSON(source1[attrname], mergedJSON[attrname]);
}
} else {//else copy the property from source1
mergedJSON[attrname] = source1[attrname];
}
}
return mergedJSON;
}
Solution 15 - Javascript
You can use Lodash
const _ = require('lodash');
let firstObject = {'email' : '[email protected]};
let secondObject = { 'name' : { 'first':message.firstName } };
_.merge(firstObject, secondObject)
Solution 16 - Javascript
A better approach from the correct solution here in order to not alter target:
function extend(){
let sources = [].slice.call(arguments, 0), result = {};
sources.forEach(function (source) {
for (let prop in source) {
result[prop] = source[prop];
}
});
return result;
}
Solution 17 - Javascript
You can do it inline, without changing any variables like this:
let obj1 = { name: 'John' };
let obj2 = { surname: 'Smith' };
let obj = Object.assign({}, obj1, obj2); // { name: 'John', surname: 'Smith' }
Solution 18 - Javascript
Let object1
and object2
be two JSON object.
var object1 = [{"name": "John"}];
var object2 = [{"location": "San Jose"}];
object1.push(object2);
This will simply append object2
in object1
:
[{"name":"John"},{"location":"San Jose"}]