Object within object add property with JavaScript - javascript

I have an object within an object. It looks like this.
var myLib = {
object1: {}
}
My basic problem is that I wanted to end up like this. So I would like to do this dynamically I will not know the property's or additional objects until run time.
var myLib = {
object1: ({"A1":({"Color":"Blue",
"height":50})
})
}
From reading here on Stack Overflow I know that I can create an object within an object by simply going like this:
myLib.Object1["A1"] = "Something"
But this does not produce what I'm looking for.
I tried this syntax which I know is wrong but basically
mylib.Object1["A1"].["color"]="Blue";
so basically here is the question. I would like to create object "A1" under "mylib.Object" and immediately add property color = "blue" to "A1". I would need to do this for several other properties, but if I can figure out how to do this for one, I can figure it out for the rest. How can I accomplish this task?
No jQuery, please. Just plain old JavaScript is what I'm looking for.**
Once I create the object and properties I would imagine I can just use a for loop to loop through the properties for that object. Like so:
for(key in mylib.Object1["A1"]){}
Right?

You can create it all from scratch like this:
var myLib = {};
myLib.object1 = {};
// assuming you get this value from your code somewhere
var x = "A1";
myLib.object1[x] = {Color: "Blue", height: 50};
Or, if all values are in variables:
var myLib = {};
myLib.object1 = {};
// assuming you get this value from your code somewhere
var x = "A1";
var colorProp = "Color";
var colorPropValue = "Blue";
var heightProp = "height";
var heightPropValue = 50;
myLib.object1[x] = {}; // create empty object so we can then add properties to it
myLib.object1[x][colorProp] = colorPropValue; // add one property
myLib.object1[x][heightProp] = heightPropValue; // add another property
These syntaxes create identical results:
myLib.object1.A1 = {};
var x = "A1";
myLib.object1[x] = {};
The first can only be used when the property name is known when you write the code and when the property name follows the proper rules for a javascript identifier. The second can be used any time, but is typically used when the property name is in a variable or when it doesn't follow the rules for a javascript identifier (like it starts with a digit).

Related

JavaScript Array with multiple items

I am trying to create a array with multiple fields in it.
For Example:
var person1 = {firstname:"Bob", lastname:"Smith", middlename:"happy"};
The problem I have is that I have 5000 variables I want to create so it would become:
var person1 = {firstname:"Bob", lastname:"Smith", middlename:"happy"};
var person2 = {firstname:"John", lastname:"Jones", middlename:"Long"};
..
var person5000 = {firstname:"Jim", lastname:"Cook", middlename:"Shorty"};
I think it would be silly to have 5000 lines of code to declare the variables.
So I want to be able to declare the variables on page load and then later assign the values to each.
I was trying to do this using the following code but I am guessing I am doing something wrong.
(I am loading some dummy data into the variables for testing)
<!DOCTYPE html>
<html>
<body>
<script>
var person = new Array (firstName:"", lastName:"", middleName:"");
for (var i = 0; i < 5000; ++i) {
person[i] = {firstName:"First"+i, lastName:"Last"+i, middlename:"Middle"+i};
}
alert(person1["firstName"]); // should alert First1
alert(person6["lastname"]); // should alert Last6
</script>
</body>
</html>
I was hoping to later in my code set the value using:
(I am pretty sure this code should work, but can't test it since I can't declare the variables correctly)
person1[firstname] = "Terry"; // should replace First1 with Terry
And then to receive a value using:
alert(person1[firstname]); // should alert Terry since it was changed
Anyone know what is wrong with my code since it's not returning the value ?
I am guessing I am declaring the variables wrong? If so how should I declare them ?
You appear to be confused about the difference between arrays and objects in Javascript. Arrays have numeric indexes, objects have named properties. So the initialization
new Array(firstName:"", lastName:"", middleName:"");
makes no sense. Not to mention, it's not valid Javascript syntax; property: value pairs can only be used in object literals, not in argument lists. If you use new Array(...), the argument should either be a single number, which is the size of the array to allocate, or a list of initial array element (with no property: prefixes. But the preferred way to create a new array is simply with the [] literal for an empty array; it will grow as necessary when you assign to it.
When you create an array, you don't get separate variables for each element. You access them using array[n] notation.
// Create an empty array
var person = [];
// Fill up the array
for (var i = 0; i < 5000; ++i) {
person[i] = {firstName:"First"+i, lastName:"Last"+i, middlename:"Middle"+i};
}
// Access elements
alert(person[1].firstName);
alert(person[6].middleName);
// Change elements
person[1].firstName = "Terry";
I believe this should work as you intended:
var person = new Array();
for (var i = 0; i < 5000; ++i) {
person[i] = {firstName:"First"+i, lastName:"Last"+i, middleName:"Middle"+i};
}
alert(person[1]["firstName"]);
alert(person[6]["lastName"]);
As pointed out by others, the person array is filled with objects, not arrays. You can use either property or associative array syntax with them.

Javascript create object with property as dynamic objects

I tried a lot searching and didnt get desired solutions.
What I want to achieve is
var myObject {
id1 : {
name:place_name,
location : place_loc
},
id2 : {
name:place_name,
location : place_loc
},
id3 : {
name:place_name,
location : place_loc
}
}
What I want to do is that Initially I want the properties "id1", "id2".. to be dynamic. And then dynamically assign name:place_name and other properties of each property.
I dont know the number of properties (id1,id2,id3...) hence would like to add them dynamically and following the addition of properties(id1,id2... ) I want to dynamically add the property values. (place_name & place_loc) of each id.
My code looks something like this.
var myObject = {};
myObject[idnumber1].place = "SomePlace1";
myObject[idnumber1].place = "SomeLoc1";
myObject[idnumber2].place = "SomePlace1";
myObject[idnumber2].place = "SomeLoc1";
But it gives error.
I know it seems simple doubt but any help would be grateful.
Thanks in advance. :)
You are trying to set a value of already assigned objects at keys "idnumber1", etc.
What you'll need is to initialize each objects for your ids like this:
var myObject = {};
myObject[idnumber1] = {};
myObject[idnumber1].place = "SomePlace1";
myObject[idnumber2] = {};
myObject[idnumber2].place = "SomeLoc1"
I would do it this way, it's not exactly what you did ask for, but I think it will become easier to change this later on.
function Place(name, location) {
this.name = name;
this.location = location;
}
var myObject = {}
myObject['id1'] = new Place('Foo', 'Bar');
myObject['id2'] = new Place('Internet', 'test');
console.log(myObject);
To dynamically create objects in your collection, you can use a numerical counter variable to create your object collection (myObject["id" + i] = {name: place_name, location: place_loc}).
An example:
var myObject = {};
for (i = 0; i < 20; i++){
myObject["id" + i] = {name: place_name, location: place_loc}
}
In practice, you can use a counter that you increment outside of a loop.

How to add a variable to a javascript/jQuery object?

Well, the problem is quite simple. I got an object of parsed table rows. Code for it is this:
var erg = [];
$("tr").each(function (index) {
var row = {};
var test = $(this).children();
row['column1'] = test[0].textContent;
row['column2'] = test[1].textContent;
row['column3'] = test[2].textContent;
row['column4'] = test[3].textContent;
row['column5'] = test[4].textContent;
row['column6'] = test[5].textContent;
row['column7'] = test[6].textContent;
erg.push(row);
});
And I wanna pass a variable var my_variable="blabla" to it without ruining the structure of the object. So how could i bring that object into a structure like this?:
Object{my_variable="my_variable_value"}, Object{my_table=[Object{...}, Object{...}]} //all the objects of the table
$.extend({}, erg, my_variable); only messed my object up.
I want it in that structure so i can pass it as json to my php script and filter my variable easily. Any tips, links, code snippets? :)
I'm not sure at which point you want to add that, but you may simply wrap your array with another object, and add your property to that same object.
This is basically what Florent's answer does, but using an object literal instead of a "class" and prototype:
// (your current code)
var wrapper = {
my_variable: 'something',
my_table: erg
};
You can define a class and add the needed variables to its prototype.
First you need a little utility to do that:
function createSharedStruct() {
// Define a shared structure
var Struct = function() {};
// Define a method to define a shared variable
Struct.share = function(variable, value) {
Struct.prototype[variable] = value;
};
return Struct;
}
And then, update your code:
// Create the shared structure
var rowClass = createSharedStruct();
// Register your shared variables
rowClass.share('my_variable', 'my_variable_value');
var erg = [];
$("tr").each(function (index) {
var test = $(this).children();
// Create a new row
var row = new rowClass();
row['column1'] = test[0].textContent;
row['column2'] = test[1].textContent;
row['column3'] = test[2].textContent;
row['column4'] = test[3].textContent;
row['column5'] = test[4].textContent;
row['column6'] = test[5].textContent;
row['column7'] = test[6].textContent;
erg.push(row);
});
// No matter when you share a variable, it will be defined among
// all instances of the same struct.
rowClass.share('my_other_var', 42);
Now you can access shared variables:
console.log(erg[0].my_other_variable); // 42
console.log(erg[1].my_other_variable); // 42
Demo available on JSFiddle.

Alternative to using eval()

I've heard a lot of rumblings about how "evil" or even "misunderstood" the eval function is, so I've decided to remove it from my code. The problem is I don't know what to replace it with.
Here's a quick rundown of my current code. I have a series of arrays (just 2 for the example below) declared at the beginning, and then based on a button click one of them gets loaded into a variable that is passed into a function.
Here's some basic HTML
<div class="button" data-name="button1">Button1</div>
<div class="button" data-name="button2">Button2</div>
and the JS (with jQuery)
var butName = null;
var eArray = null;
var button1Logo = ["..path/to/pic1.png","..path/to/pic2.png"];
var button2Logo = ["..path/to/pic3.png","..path/to/pic4.png"];
$(".button").mouseup(function(){
/*give a butName*/
butName = $(this).attr("data-name");
/*give the array from the button*/
eArray = eval(butName + "Logo");
});
Doing it this way assigns the array to the variable and not just a string that says "butnameLogo" which is why I used eval. But I'm looking to get away from that.
I know I can add a new attribute to the html and just retrieve that for the variable but I don't want to add more html when I can possibly do it with JS.
I've also tried making an object with strings loaded into it as seen in this answer: https://stackoverflow.com/a/16038097/1621380 but that resulted in just a string again, and not assigning a variable.
Wondering if you smart people have any better suggestions!
Replace
var button1Logo = ["..path/to/pic1.png","..path/to/pic2.png"];
var button2Logo = ["..path/to/pic3.png","..path/to/pic4.png"];
with an object, where the keys are your button names:
var buttonLogos = {
button1: ["..path/to/pic1.png","..path/to/pic2.png"],
button2: ["..path/to/pic3.png","..path/to/pic4.png"]
};
Then instead of the eval you can simply do
eArray = buttonLogos[butName]
(or buttonLogos[butName + "Logo"] if you want to call the keys button1Logo and button2Logo, but I can't really see the point now that they are nicely contained within a buttonLogos object)
Use an object:
var butName = null;
var buttonsLogos = {
button1: ["..path/to/pic1.png", "..path/to/pic2.png"],
button2: ["..path/to/pic3.png", "..path/to/pic4.png"]
};
$(".button").mouseup(function(){
/*give a butName*/
butName = $(this).attr("data-name");
/*give the array from the button*/
eArray = buttonsLogos[butName];
});
Consider making the data available as properties of an object, then you can control access to the object through scope and only need one (global?) variable for all such data.
If global scope is needed, then:
var dataObj = {
button1Logo: ["..path/to/pic1.png","..path/to/pic2.png"],
button2Logo: ["..path/to/pic3.png","..path/to/pic4.png"]
}
and later:
var eArray = dataObj[this.data-name + 'Logo'];
You may want to call the data object something more meaningful than dataObj though.
The best option is to define an object which holds all our button paths:
var buttons = {
"1": ["..path/to/pic1.png", "..path/to/pic2.png"],
"2": ["..path/to/pic3.png", "..path/to/pic4.png"]
};
$(".button").mouseup(function(){
/* give a butName */
var butName = $(this).attr("data-name");
/* give the array from the button */
var eArray = buttons[butName];
});
If your variables reside in the global scope, you could use the bracket notation to access them:
eArray = window[butName + "Logo"];
Note that this solution is not recommended. The first code sample is much cleaner and more maintainable.
Imagine a situation where you would have to move all the code into a 'deeper' context (!= global context). Nothing would work anymore.
You can do this very nicely with arrays and array indexes. You needn't find and use variable names at all. Even your data- attributes are unnecessary.
var eArray;
var buttonLogos = [
["..path/to/pic1.png","..path/to/pic2.png"],
["..path/to/pic3.png","..path/to/pic4.png"]
];
var buttons = $(".button").mouseup(function(){
var idx = buttons.index(this);
eArray = buttonLogos[idx];
});
The key line in this is buttons.index(this). This method call gets the position of the current element among all the elements matched by $(".button"). We then use this index to select the relevant element from the buttonLogos array.
You're taking a very circuitous route by using eval here.
You'd be much better off doing something like this:
var paths = {
button1: ["..path/to/pic1.png","..path/to/pic2.png"],
button2: ["..path/to/pic3.png","..path/to/pic4.png"]
};
$(".button").mouseup(function(){
/*give the array from the button*/
eArray = paths[$(this).attr("data-name")];
});
eval should only be used if you need to execute code (usually from a 3rd party source), and even that is rare. If you ever find yourself saying "i should use eval here", there's almost definitely a better alternative, and you should try and find it.

How can I use multiple variables to retrieve JS objects?

I'm only working on my 3rd Javascript project, so this is probably easy to answer (at least I hope so).
I have learned to use JS object in place of arrays. In this project I have named multiple object with a nested system of IDs as follows:
animalia = new Object();
animalia.chordata = new Object();
animalia.chordata.actinopterygii = new Object();
animalia.chordata.actinopterygii.acipenseriformes = new Object();
etc.......
I'm having problems calling on objects named this way though. Here is my code:
function expand(event){
var target = event.target;
console.log(target);
var parent = target.parentNode;
console.log(parent);
var parentclass = parent.getAttribute("class");
console.log(parentclass);
if (parentclass == "kingdom"){
var newdiv = document.createElement("div");
var newexpctrl = document.createElement("div");
var parentid = parent.getAttribute("id");
console.log(parentid);
----> var parentobj = window[parentid];
console.log(parentobj);}
else{
var upperclass = searchArray(parentclass);
console.log(upperclass);
var newdiv = document.createElement("div");
var newexpctrl = document.createElement("div");
var parentId = parent.getAttribute("id");
console.log(parentId);
var parentnode_ = document.getElementById(parentId);
console.log(parentnode_);
var gparentId = parentnode_.parentNode.id;
console.log(gparentId);
----> var parentobj = window[gparentId.parentId];
console.log(parentobj);
}
var childnumb = parentobj.children;
}
I am having my problem with the two statements indicated by "---->". In the first case, using a single variable works for pulling up the proper object. However, in the second case, using two variables, I fail to be able to access the proper object. What is the proper syntax for doing this? I have tried a plethora of different syntax combinations, but nothing seems to work correctly. Or should is there a better method for calling on JS objects other than using "window[variable]"?
P.S.- If you haven't figured it out by now, I am working on educational tools for use in learning biology. Thanks once again stackoverflow, you guys rule.
Assuming that the window object has something w/ the property matching a string that's the value of gparentId, you should be able to do:
var parentobj = window[gparentId][parentId];
The problem here is that the square bracket's notation is being applied to too much. gparentId is a string. It doesn't have a property called parentId. You therefore have to do this in two steps. First get:
window[gparentId]
Then get the appropriate property of that object
var parentobj = window[gparentId][parentId];
On a somewhat unrelated note, this isn't very well written JavaScript code:
Creating Objects
When creating new objects, always use the following syntax:
var obj = {};
That's what's generally been accepted as standard, so it's easier for people to read.
Declaring Variables in If Statements
You shouldn't really declare variables inside an if statement, especially when declaring the same variable in the else block, that's really confusing. Instead, declare all the variables at the top in a list and then use them without the var keyword lower down.
var newdiv = document.createElement("div"),
newexpctrl = document.createElement("div"),
parentid = parent.getAttribute("id"),
parentobj;
Note the commas instead of semi-colons which means I don't have to repeat the var keyword. Since the values of newdiv, newexpctrl and parentid are the same in either case, I give them their values straight away, making the contents of the if statement much shorter and easier to digest.
Result
function expand(event){
var target = event.target;
var parent = target.parentNode;
var parentclass = parent.getAttribute("class");
var newdiv = document.createElement("div"),
newexpctrl = document.createElement("div"),
parentid = parent.getAttribute("id"),
parentobj, upperclass;
if (parentclass == "kingdom"){
parentobj = window[parentid];
}else{
upperclass = searchArray(parentclass);
var _parentId = document.getElementById(parentId).parentNode.id;
parentobj = window[_parentId][parentId];
}
var childnumb = parentobj.children;
}
Note that I've left var _parentId inside the if since I think it probably improves readability, but you may choose to take it outside the if, since it will pollute the namespace of the function anyway.

Categories