I have an object inside an object, the name of the object could change, how can I get the value inside of the object's object without referring to it by name?
Object {medium-editor-1453741508068-0: Object}
medium-editor-1453741508068-0: Object
value: "this is what i want"
This gets the above:
this.mediumEditor.editor.serialize();
I need something like:
this.mediumEditor.editor.serialize().childObject.value;
If your top-level object only contains one object, you can simply use Object.keys(topLevelObject) to get the "object's object" name. Something like the following:
var objectsObjectName = Object.keys(topLevelObject)[0];
var value = topLevelObject[objectsObjectName].value;
The same logic can be used recursively if you have more levels of object nesting, or if the object's object's value's name (wow, this is getting hard to follow) is non-predictable too.
You can also iterate on the top-level object:
for (var key in topLevelObject) {
var value = topLevelObject[key].value;
}
This works even if you only have one nested object, even though it's arguably weird to write a loop knowing it will only loop once.
Related
I have created a copy of a variable using Object.assign and I am able to change an array within the copy of the object fine without affecting the original object. However, if I try and update a value within an array on the copied object this is also affecting the original object (i.e. the changes are made to both "job" and "updatedJob").
I have the following code:
// Create copy of "job" object which has been passed through
let updatedJob = Object.assign({}, job);
// Remove images from updated job object
updatedJob.Images = null;
// Remove checklist images from updated job object
_.each(updatedJob.Checklists, function (checklist) { checklist.Image = null; });
As you can see I have created a copy of the "job" object that has been passed through.
If I then change the "Images" array of the "updateJob" object (to null) this works fine and does not affect the original "job" object (i.e. the original "job" object still has images intact).
However in the last line of the code I am trying to iterate the "Checklists" array witin the "updatedJob" object and change just the "Image" property to "null" for each one but doing this also updates the original "job" object.
How is this possible when the "updatedJob" object should be a copy of the original "job" object therefore any changes I make to it should not affect the original "job" object?
As stated in comments and other answers, you're doing a shallow copy. Does that _.each() in your code indicate that you're using lodash?
If so, use the deepClone() method so that items are copied recursively:
let updatedJob = _.cloneDeep(job)
Otherwise, there are other questions on SO that deal with this topic that will provide a suitable solution.
Object.assign does a shallow copy: It copies all the key-value pairs of one object into another, just like this:
const from = { primitive: "string", complex: { } }, to = {};
// Object.assign(from, to) basically does
to.primitive = from.primitive; // primitives are copied
to.complex = from.complex; // complex values references get copied, not the value itself
However, objects (arrays are objects too) are copied by reference, so in your case, both objects' Checklists properties point to the same array.
You could create a new array by using .map and reassign the property to point to the new array:
updatedJob.Checklists = updatedJob.Checklists.map(checklist => ({ ...checklist, Image: null }));
The reference thing here applies here again too, setting .Image to null would affect the object referenced in both arrays, therefore we have to copy these objects too.
How to know the type of variable containing the result of document.getElementById()?
For example, on using alert(typeof variable), I get object but we refer these variables like array in document.getElementsByClassName[i].
I want to know what exactly is the type of the variable containing the value and how are we using it as an array.
var cv = document.getElementById("xyz");
alert(typeof cv); //Alerts object
But we use these variables as arrays like..
var cv = document.getElementsByClassName("xyz");
cv[0].style.height="200px"; //use as array
On evaluating it further using array.isarray(),it turns out that it is not an array..So how are we able to use the variable as an array like in the code written "use as array"?
Welcome to Stack Overflow.
typeof returns object for both arrays and objects, all it means is that it is a non-primitive data type.
If you are interested in determining if it is an array, you can use Array.isArray() like this
const values = [1,2,3]
if (Array.isArray(values))
console.log("It's an array")
Notice that I used console.log instead of alert(), if you have many of them it doesn't hold up the execution.
document.getElementById gives you a reference to a single DOM Element object
document.getElementsByClassName gives you an array-like object, which is a live HTMLCollection of found elements
I'm trying to learn to program. I've gone through a list of tutorials sites online and I'm stuck on a thing that I think is extremely important for me to understand.
My questions:
(This is what I'd like to understand most) In my for...in loop, why is creating new "obj" objects using the "Contacts" constructor working? It seems like I would need a different name each time I loop so that I don't overwrite the object that I've created the pass before. If this is correct, how do I do this if I don't know anything about the number or value of contacts ahead of time? Additionally, why does the title of the any of the objects in the console logs not say obj? Am I confused about what it means to create an instance of an object? Are the names of these instances unimportant?
Why are all of the properties undefined? Should referencing properties from the temporary "i" variable work?
Creating objects from an unknown total of data entries seems really important. Unfortunately, places like Codecademy fall short here. You always manually create new instances of objects with hardcoded names they give you. But what would happen if there were two of the same name?
Thanks so much for any help I may get on this. Don't hold back from telling me anything else silly that I may be doing.
Here is a link to a console screenshot - http://i.imgur.com/TK4dtfV.png
var TestApp = {};
// my data... taken from wherever
TestApp.jsonContacts = {
contact1: {
name: "Ethan",
age: 24
},
contact2: {
name: "Evan",
age: 30
},
contact3: {
name: "Paul",
age: 9000
}
};
// I know this is silly, just let me pretend...
TestApp.jsonStrung = JSON.stringify(TestApp.jsonContacts);
TestApp.globalContactList = [];
// my constructor function to create instances of Contact
TestApp.Contact = function(name, age){
this.name = name;
this.age = age;
TestApp.globalContactList.push(this);
};
// where I'm taking data and creating new Contact objects
TestApp.instantiateObjects = function(){
// I know this is silly, just let me pretend...
var jsonUnstrung = JSON.parse(TestApp.jsonStrung);
// I think I'm looping through the first set of objects sitting in jsonContacts
for (var i in jsonUnstrung) {
var obj = new TestApp.Contact(i.name, i.age);
console.log(obj);
}
console.log(TestApp.globalContactList);
};
TestApp.instantiateObjects();
In my for...in loop, why is creating new "obj" objects using the "Contacts" constructor working?
A variable is just a holding place for a value. It is not the value itself. If you overwrite a variable with a new value, the previous value it held will continue to exist as long as something is holding a reference to it; it's simply that the variable won't be referring to it anymore.
It seems like I would need a different name each time I loop so that I don't overwrite the object that I've created the pass before.
No, you don't. One variable is fine, as long as you do something with the value before you assign the variable to the next value.
If this is correct, how do I do this if I don't know anything about the number or value of contacts ahead of time?
It doesn't matter how many you have.
Additionally, why does the title of the any of the objects in the console logs not say obj?
console.log() prints out the value that is passed to it. It doesn't care (doesn't know) anything about the variable that you pass to it.
Am I confused about what it means to create an instance of an object?
It seems so. Creating an instance of an object allocates some memory to store that object's values. A variable allows you to gain access to that allocated object.
Are the names of these instances unimportant?
Yes, object instances don't have names.
Why are all of the properties undefined?
i holds the property names of the object you are iterating through, so in this case, the strings "contact1", "contact2", "contact3". These strings don't have a name or age property, so your constructor is receiving two undefined values.
Should referencing properties from the temporary "i" variable work?
You need to use i as a property name to access the property values:
var obj = new TestApp.Contact(jsonUnstrung[i].name, jsonUnstrung[i].age);
In general, it's a good idea not to have side-effects like TestApp.globalContactList.push(this); in a constructor. There may be cases where doing so makes sense, but most of the time, removing that line and doing this would be preferable:
for (var i in jsonUnstrung) {
var contact = jsonUnstrung[i];
var obj = new TestApp.Contact(contact.name, contact.age);
console.log(obj);
TestApp.globalContactList.push(obj);
}
I'm working on existing Javascript code, which uses datasets stored in objects which are named data1, data2, etc. The numbers are IDs taken from a database.
Now, I need to write a little additional function which takes the IDs as input, then constructs the appropriate object name using that Id, and then passes that object to a function as a parameter.
So, something like:
function doStuff(id){
var objname="data"+id;
//now, I need to pass the object (not just the name) to a function
someFunction(objname); //this obviously doesn't work, because it just passes the object name as a string
}
So, how do I pass the actual object to the function, given that I have the object name?
The question sounds elementary, and I assume there's a method which does just this, but google doesn't seem to help.
Since the objects exist, you need a way to "find" them. I suggest you create a relationship between the string and the object using a key-value array - the key is the string, and the value is the object. You can then index the array with the string, and it will return the object.
Create an object and store in it keys like so:
var obj = {
data0 : "example 1",
data1 : "example 2"
}
Then you can access the properties like so:
function doStuff(id) {
var key = "data" + id;
someFunction(key);
}
someFunction(key) {
return obj[key];
}
My javascript looks like:
[{"user":{"property1":8,"property2":"asdfasdf"}}];
I tried:
alert(user.property1);
But nothing rendered, what am I missing here?
Your javascript is an array, I assume it's assigned to a variable?
var myArray = [{"user":{"property1":8,"property2":"asdfasdf"}}];
alert(myArray[0].user.property1);
You don't seem to assign the object literal to a variable. You must do that in order to be able to reference it the way you seem to want. Note that [] indicates an array.
So you're almost there:
var myObj = [{"user":{"property1":8,"property2":"asdfasdf"}}];
alert(myObj[0].user.property1);
Your object literal creates an array, with an object that has a property named user. This user property itself is set to an object which has two properties - property1 and property2.