I have a requirement to merge two (or Multiple) Objects as a single object. While keeping each Object name as the parent key.
var event =
{ id : '45243'
, name : 'Cardiff locè'
, loc : 'Cardiff'
}
var alert =
{ node : 'sdwan edge'
, severity : 'critical'
}
The output should be like this:
var mergedObject =
{ event :
{ id : '45243'
, name : 'Cardiff loc'
, loc : 'Cardiff'
}
, alert:
{ node : 'sdwan edge'
, severity : 'critical'
}
}
mergeObject.event = event;
mergeObject.alert = alert;
That's not really merging. The existing objects are unchanged. You are just creating a new object.
var mergedObject = {
"event": event,
"alert": alert
};
var event = {
"id": "45243",
"name": "Cardiff loc",
"loc": "Cardiff"
}
var alert = {
"node": "sdwan edge",
"severity": "critical"
}
var mergedObject = {
event,
alert
};
console.log(mergedObject)
Related
I am trying to read the data from firebase database, and display the same in a webpage.
My database structure is as below -
If you see the image, i am able to read the "UserData" using the below code -
firebase.initializeApp(config);
var database = firebase.database();
var ref = database.ref('UserData');
ref.once('value', gotData1, errData);
function gotData1(data){
//console.log(data.val());
var usrData = data.val();
var keys = Object.keys(usrData);
//console.log(keys);
for (var i = 0; i< keys.length; i++){
var k = keys[i];
var id = usrData[k].AssignedID;
var name = usrData[k].Name;
$(document).ready(function() {
var $formrow = '<tr><td>'+id+'</td><td>'+name+'</td></tr>';
$('#userInfo').append($formrow);
});
}
}
In the highlighted part of the image, you can see keys with values 196214, 196215, 196216
Now, I need to fetch the values for "One, Count" by matching the key values with available AssignedID.
How can i achieve the same?
Update, JSON as text -
{
"app_url" : "https://app_name?ls=1&mt=8",
"UserData" : {
"HNpTPoCiAYMZEeVOs01ncfGBj6X2" : {
"Name" : "Arunima Vj"
"Email" : "asd#upp.com",
"AssignedID" : 196214
},
"VXU2tdGdzZX90PJa9mpEL3zAiZo2" : {
"Name" : "Lakshman Medicherla"
"Email" : "asd#upp.com",
"AssignedID" : 196215
},
"dFlwtqDNrja2RkOySVtW106IQP62" : {
"Name" : "Prashanth Sripathi"
"Email" : "asd#upp.com",
"AssignedID" : 196216
}
}
"teams" : {
"196214" : {
"1105" : {
"One" : 7619,
"count" : 24
},
"1379" : {
"Two" : 7145,
"count" : 21
}
},
"196215" : {
"1111" : {
"One" : 7779,
"count" : 20
},
"1508" : {
"Two" : 1176,
"count" : 21
}
},
"196216" : {
"1106" : {
"One" : 7845,
"count" : 22
},
"1509" : {
"Two" : 1156,
"count" : 26
}
}
}
}
Your data structure is quite nested, which makes the code more difficult to read. But this navigates the structure generically in the minimum code I could come up with:
var ref = firebase.database().ref("/42824688");
ref.child("UserData").once('value', gotUserData);
function gotUserData(snapshot){
snapshot.forEach(userSnapshot => {
var k = userSnapshot.key;
var id = userSnapshot.val().AssignedID;
var name = userSnapshot.val().Name;
ref.child("teams").child(id).once("value", teamsSnapshot => {
teamsSnapshot.forEach(teamSnapshot => {
var teamKey = teamSnapshot.key;
teamSnapshot.forEach(teamProp => {
var prop = teamProp.key;
var val = teamProp.val();
console.log(k+" "+name+" "+id+": "+teamKey+", "+prop+"="+val);
});
});
});
})
}
So for each user, this loads the teams data for that user and then loops over the teamsSnapshot to get each teamSnapshot and then loops over that to get each team property.
Working jsbin: http://jsbin.com/noziri/edit?html,js,console
I have several Ajax-requests that retrieves data from the server...
I want to add them together, so I can use the data set later.
This is how one JSON-looks like:
{
"51" : { id:"51", name:"frank" },
"52" : { id:"52", name:"jonny" }
}
A second later there might come another one, with the exactly the same structure. How do I just "append" a new json into this to make a large object with the same structure..
EG: (append like this)
{
"51" : { id:"51", name:"frank" },
"52" : { id:"52", name:"jonny" },
"72" : { id:"72", name:"daniel"},
"73" : { id:"73", name:"lisa"},
"74" : { id:"74", name:"ida"},
"75" : { id:"75", name:"ali"}
}
Assuming that the ID will always be unique, you can do something like:
var buffer = {};
messageSource.on('message', function (msg) {
var msgKeys = Object.keys(msg); // Get the list of IDs
msgKeys.forEach(function (key) { // For each numeric key...
buffer[key] = msg[key]; // Copy the message
});
});
If you cannot guarantee unique IDs, you'll need some minor changes:
var buffer = {};
messageSource.on('message', function (msg) {
var msgKeys = Object.keys(msg);
msgKeys.forEach(function (key) {
buffer[key] = (buffer[key] || []).push(msg[key]); // Only change, append to list for that key
});
});
You should use Jquery $.merge:
var obj1 = {
"51" : { id:"51", name:"frank" },
"52" : { id:"52", name:"jonny" }
};
var obj2 = {
"72" : { id:"72", name:"daniel"},
"73" : { id:"73", name:"lisa"},
"74" : { id:"74", name:"ida"},
"75" : { id:"75", name:"ali"}
}
var result = $.extend(obj1, obj2);
Working exemple here
I am using a Module Pattern in a javascript code, initially i have to make a private property equal to another, but it looks like it's just a symlink, like in the example.
I need two independant private properties but sometimes sync them.
Thanks for help.
Maxime.
var module = (function () {
var data1 = {
pro1 : "aaa",
pro2 : "bbb"
};
var data2 = {};
function init() {
data2 = data1;
}
function logg() {
console.log(data1);
console.log(data2);
}
function test() {
data2.pro1 = 'haha';
}
return {
init : init,
logg : logg,
test : test
}
}());
module.init();
module.logg();
// data1 = { pro1 : "aaa", pro2 : "bbb" }
// data2 = { pro1 : "aaa", pro2 : "bbb" }
module.test();
module.logg();
// data1 = { pro1 : "haha", pro2 : "bbb" }
// data2 = { pro1 : "haha", pro2 : "bbb" }
If your simple object example is similar to the structure you're going to be using, aka no prototypical inheritances from your objects, you could loop through your object and assign values from your old to new. Otherwise your simple assignment will just be pass by reference.
ie:
for(var i in data1){
data2[i] = data1[i];
}
solution
I am still getting the hang of it, and its probally logic for a lot of you. But I've updated the post with how I got it working, might some one come here by search.
declare:
var test=Element({"id" : 1, "name" : "wrapper"}).
append(Element({"id" : 2, "name" : "elm A"}),
Element({"id" : 3, "name" : "elm b"})
);
alert(test.getInfo("name"));
alert(test.aArguments["children"][1].getInfo("name"));
'class':
var Element = function ($aPassArguments) {
aArguments: {
"id" : false,
"name" : false,
"type" : false,
"title" : false,
"style" : false,
"action" : [],
"parent" : false,
"children" : []
};
for (var prop in this.aArguments)
if (prop in $aPassArguments)
this.aArguments[prop] = $aPassArguments[prop];
return {
append: function () {
$argList = arguments;
for ($i = 0; $i < $argList.length; $i++)
if (typeof $argList[$i]=="string")
this.setChild(this.importDB($argList[$i],true));
else
this.setChild($argList[$i]);
},
setChild: function($oChild) {
this.aArguments["children"][this.aArguments["children"].length]=$oChild;
}
};
};
.............................................................
Previous edit
I wasnt aware a new object instance in javascript is a reference instead of a copy. Now I want to have a copy of my own object Element. Apperantly (thanks #blurd) I want it to be a factory hybrid:
http://javascript.info/tutorial/factory-constructor-pattern
Thanks to the help of #blurd and me defining some problems, I came up with a sollution like the following:
(but I am not happying with my usage declaration below)
In which I finaly got copies of my Element object instead of references. The good answers below didnt completly solve my problem. But this is due to my poor clarification and understanding of the problems
Sort of solution
var Element = function (initialConfig) {
return {
aArguments: {
"id" : false,
"name" : false,
"type" : false,
"title" : false,
"style" : false,
"action" : [],
"parent" : false,
"children" : [],
},
create:function ($aPassArguments) {
for (var prop in this.aArguments)
if (prop in $aPassArguments)
this.aArguments[prop] = $aPassArguments[prop];
},
append: function () {
$argList = arguments;
for ($i = 0; $i < $argList.length; $i++)
if (typeof $argList[$i]=="string")
this.setChild(this.importDB($argList[$i],true));
else
this.setChild($argList[$i]);
},
setChild: function($oChild) {
this.aArguments["children"][this.aArguments["children"].length]=$oChild;
}
};
};
usage
var test=Element();
test.create({"id" : 1, "name" : "wrapper"});
var test2=Element();
test2.create({"id" : 2, "name" : "elm A"});
test3.create({"id" : 3, "name" : "elm B"});
test.append(test2,test3);
alert(test.aArguments["name"]);
alert(test.aArguments["children"][0].aArguments["name"]);
Now I am very unhappy about the usage,I would like it be one line and use a constructor again. And this is probally possible, and... after some more selfschooling I will probally solve it. But for now I am done with it :P just updated my post with this. When I get to it again and have a beter declaration I will update it again. And perhaps someone might share a way (beter way) to do this. To eventually have something like this:
var test=new Element({"id" : 3, "name" : "wrapper"})
.append( new Element{"id" : 3, "name" : "elm A"}),
new Element({"id" : 3, "name" : "elm B"})
);
.............................................................................................
old post
I am pulling my hair outs here, everything I search about javascript and objects tells me the same, which is not enough, because I cant figure out why the following code isnt working propaly:
For example I am making an object like this:
var Element = {
aArguments: { //set Default arguments
"id" : false,
"name" : false,
"type" : false,
"title" : false,
"style" : false,
"action" : [],
"parent" : false,
"children" : {},
},
create:function ($aPassArguments) {
for (var prop in this.aArguments)
if (prop in $aPassArguments)
this.aArguments[prop] = $aPassArguments[prop];
return this;
},
append: function () {
$argList = arguments;
for ($i = 0; $i < $argList.length-1; $i++)
if (typeof $argList[$i]=="string")
this.setChild(this.importDB($argList[$i],true));
else
this.setChild($argList[$i]);
return this;
},
setChild: function($oChild) {
this.aArguments["children"][this.aArguments["children"].length-1]=$oChild;
},
getInfo: function($sKey) {
return this.aArguments[$sKey];
}
};
Which merges $aPassArguments with this.Arguments on calling of .create() (I cant figureif its possible to use a '__constructor'). To replace given proparties in aArguments.
And add passed object(s) with .append to aArguments["childeren"].
But when I call the object like this:
$set=(Element.create({"id": 1, "name" : "wrapper"})).
append(Element.create({"id" : 3, "name" : "elm A"}));
alert($set.getInfo("name"));
It will alert me "Elm A" and not "wrapper".
I assume that this is because I am not creating a new object of Element, but are working on the same object. Now to me the logical solution and start would be to write:
$set=(new Element.create({"id": 1, "name" : "wrapper"})).
append(new Element.create({"id" : 3, "name" : "elm A"}));
alert($set.getInfo("name"));
but I get the error:
TypeError: (intermediate value).append is not a function
Why isnt my code not working as supposed by me?
And is it possible and if so how do I add a constructor to an object? So I could skip calling .create and use:
$set=new Element({"id": 1, "name" : "wrapper"}).
append(new Element({"id" : 3, "name" : "elm A"}));
You are right, you should be using the new operator. Aside from that, it looks like you're trying to make this some type of factory hybrid. I suggest the following.
Use a Constructor Function
Include an optional configuration that you can use when creating the object.
var Element = function (initialConfig) {
if (initialConfig) {
this.create(initialConfig);
}
};
Add to the Prototype
All your shared Element members should be part of the prototype.
Element.prototype = {
aArguments: {
"id" : false,
"name" : false,
"type" : false,
"title" : false,
"style" : false,
"action" : [],
"parent" : false,
"children" : {},
},
create:function ($aPassArguments) {
for (var prop in this.aArguments)
if (prop in $aPassArguments)
this.aArguments[prop] = $aPassArguments[prop];
return this;
},
append: function () {
$argList = arguments;
for ($i = 0; $i < $argList.length-1; $i++)
if (typeof $argList[$i]=="string")
this.setChild(this.importDB($argList[$i],true));
else
this.setChild($argList[$i]);
return this;
},
setChild: function($oChild) {
this.aArguments["children"][this.aArguments["children"].length-1]=$oChild;
},
getInfo: function($sKey) {
return this.aArguments[$sKey];
}
};
Examples
Your examples should now work as you expected. Notice that you can't call new Element.create() as that would treat Element.create as a constructor. Instead, pass your initial values into the constructor.
$set = new Element({"id": 1, "name" : "wrapper"}).
append(new Element({"id" : 3, "name" : "elm A"}));
alert($set.getInfo("name"));
Be Careful
You're not checking for own properties in your loops, omitting {}, and I spotted at least one implied global. JavaScript will bite you if you're not careful. Consider using JSLint or JSHint to help you spot these problems.
Your create function does not create any object, but rather changes on place the Element. aArguments object. Any strange thing might follow.
Anyway, just go for a clean and simple prototypal inheritance scheme, do not use $, remember to always declare your vars, and keep things simple :
function Element(initialValues) {
this.id = this.prototype.id++;
this.name = null;
this.type = null;
this.title = null;
this.style = null;
this.action = [];
this.parent = null;
this.children = [];
for (var prop in initialValues)
if (this[prop] != undefined) this[prop] = initialValues[prop];
}
Element.prototype = {
append: function () {
for (var i = 0; i < arguments.length - 1; i++) {
var thisElement = arguments[i];
if (typeof thisElement == "string") this.setChild(this.importDB(thisElement, true));
else this.setChild(thisElement);
}
return this;
},
setChild: function (child) {
this.children.push(child);
return this;
},
getInfo: function (key) {
return this[Key];
},
id: 0
};
How can I change the name of a node in my JSON?
My code:
childType = view
childName = view0
child=[];
child[childTipy]= {
childType:{
"tipo": childTipy,
"nome":childName,
}
};
childList.push(child[childTipy]);
minhasWindows = {"window": {
"nome": "Win2",
"title": "Win",
"childrens": childList
}
};
The resulting JSON:
{
"windows" : [
{
"window" : {
"nome" : "Win2",
"title" : "Win",
"childrens" : [
{
"childType" : {
"tipo" : "view",
"nome" : "view0"
}
}
]
}
}
]
}
I want the childType node to be the value of my var childType = "view". How can I change this?
PS: I have multiple childType values.
If you want the property to come from a variable, use array syntax to assign the property.
var childType = "view"; // String needs to be quoted
var childName = "view0"; // String needs to be quoted
var child = {}; // This must be an object, not array
child[childType] = {
tipo: childType, // Don't need to quote keys in object literals
nome: childName,
};
childList.push(child);
You also had too many levels in your child object.
Change this
childType:{
to
view:{
Replace
child=[];
child[childTipy]= {
childType:{
"tipo": childTipy,
"nome":childName,
}
};
with
child=[];
child[childTipy]= {};
child[childTipy][childType] = {
"tipo": childTipy,
"nome":childName,
};
If childType appears in the keys only:
var someJson = '{"windows":[{"window":{"nome":"Win2","title":"Win","childrens":[{"childType":{"tipo":"view","nome":"view0"}}]}}]}';
var newJson = $.parseJSON(someJson.replace('childType', 'view'));
Though I don't see any actual need of changing a key in place.