How to extend object child without rewriting it [duplicate] - javascript

This question already has answers here:
How to deep merge instead of shallow merge?
(47 answers)
Closed 2 years ago.
I have a json object containing information about a person, and I want to update the data using jQuery extend function, the problem is that the child gets rewritten.
example:
var dadThen = {
name: "Adam",
age: 35,
child:{
name: "Ben",
age: 10
}
}
// dad now
var dadNow = {
age: 36,
child: {
age: 11
}
}
var newData = $.extend({}, dadThen, dadNow);
// The child name gets removed
// newData.child.name is undefined
How to fix this?

Isnt it like this
var newData = $.extend(true, {}, dadThen, dadNow);
first parameter is a flag whether to deep clone the object.

Related

Javascript Map() object has confusing behaviour [duplicate]

This question already has answers here:
Object copy using Spread operator actually shallow or deep?
(4 answers)
Closed 6 months ago.
I have a use case that I thought the Map object would be perfect for but there is confusing behaviour that appears to me as a bug, but Im after any information as to why this happens and possibly a solution to the behaviour.
For instance, say I have 2 objects:
const obj1 = { name: "John" };
const obj2 = { name: "Jane", age: 35 };
And I have defined and extra object for extra properties to add to both objects later:
const extProps = { gender: "unspecified", children: [] };
Create a new Map object and add the 2 objects:
const map = new Map();
map.set(obj1.name, obj1);
map.set(obj2.name, obj2);
Due to the objects being reference types I can assign the extra props like so:
Object.assign(obj1, { ...extProps });
Object.assign(obj2, { ...extProps });
Now I can get the values from the map using the keys like:
const johnObj = map.get("John");
const janeObj = map.get("Jane");
And the object have all the extra props like expected. The following statements update the individual objects in the map:
janeObj.gender = "female";
johnObj.age = 45;
Here is where the confusing behaviour I see is happening...
If I add an entry to the children array of either objects, it updates both
johnObj.children.push("jack");
obj2.children.push("jenny");
name: "John"
gender: "unspecified"
children: ["jack", "jenny"]
age: 45
name: "Jane"
age: 35
gender: "female"
children: ["jack", "jenny"]
What am I missing??
Like Konrad said in his comment, "arrays are also objects and are reference types".
The issue is that the spread operator (...) only goes on level deep, so for the array in extProps, is it not copied, it is the same one.
To solve this you can use a recursive function to "deep copy" an object.
Here is an example of a deep copy function:
const deepCopy = objIn => {
if (typeof objIn !== 'object' || objIn === null) return objIn;
let objOut = Array.isArray(objIn) ? [] : {};
for (const key in objIn) {
objOut[key] = deepCopy(objIn[key]);
}
return objOut;
}

State variable changes unpredictably - ReactJS [duplicate]

This question already has answers here:
Is this a good way to clone an object in ES6?
(10 answers)
What is the most efficient way to deep clone an object in JavaScript?
(67 answers)
Closed 2 years ago.
I am a newbie in React. I need some help to solve this issue
Code:
this.state={
testState: {
testArray: [
{ name: "bob" },
{ name: "alice" },
{ name: "john" }
]
}
}
testFn = () => {
let a;
a = { ...this.state.testState }; //using spread operator to copy the object instead of referencing
a.testArray.map((obj) => {
obj.name = "React is awesome"
})
console.log(this.state.testState)
}
Output:
testArray: Array(3)
0: {name: "React is awesome"}
1: {name: "React is awesome"}
2: {name: "React is awesome"}
I have to modify a without altering the state. But here, the state is also changed along with the iteration.
How can I solve this problem?
The spread operator only does a shallow copy
To guarantee a full object copy use
const copiedState = JSON.parse(JSON.stringify(yourState))
Better solution
Sove it at the source. Don't make deep state, its actually a key part of writing objects in the state. You should keep them very shallow. In this case you are already way deep with Obj -> Array -> Obj.

using nested destructuring with aliasing for javascript Object [duplicate]

This question already has answers here:
Destructuring deep properties
(4 answers)
Closed 4 years ago.
I have this object
const storeObj = {
name: {
firstName: 'abc'
}
}
I can do alias by assigning name to username
const { name: username } = storeObj
I can do nested destructuring like so
const { name: { firstName } } = storeObj
Can I use them both together? I want to achieve one line when aliasing aka renanming and nested destructuring.
Yes, just put those two together - when you want to assign to a different variable name than the property name, put the new variable name after a colon. This works regardless of the level of the nested object.
const storeObj = {
name: {
firstName: 'abc'
}
}
const { name: { firstName: username } } = storeObj;
console.log(username);

Create id and check if it exists in an object array [duplicate]

This question already has answers here:
How to find object in array by property in javascript?
(3 answers)
Closed 5 years ago.
How generate a unique id and push it through an object to an array, on condition that this id property value does not already exist in any of the array objects?
As per React code excerpt below, function "saveColor" was supposed to do that, attaching current state background color, so that an object would look similarily to those in the palettes array:
state = {
backgroundColor: "red",
palettes: [
{id: 2, color: "crimson"},
{id: 1, color: "skyblue"},
{id: 0, color: "rebeccapurple"},
{id: 4, color: "magenta"}
]
}
saveColor = () => {
let previousPalettes = this.state.palettes;
previousPalettes.push(this.state.backgroundColor);
this.setState({
palettes: previousPalettes
})
}
It is not clear why you need id here, but if you really need it - look at this package https://www.npmjs.com/package/uuid

Iterating though object in array in React (ES6) [duplicate]

This question already has answers here:
How to iterate over a JavaScript object?
(19 answers)
Closed 5 years ago.
I have an object in array like the following:
bears: [
{
Yogi: "123kg",
Pooh: "110kg",
Grizly: "112kg",
BooBoo: "200kg",
Polar: "100kg",
}
]
`
What is the best way to iterate through such object in order to display both names and values in the row, like returning something in the type of: <p>${name} ${value}</p>
So I would display:
Yogi 123kg
Pooh 110kg
Grizly 112kg
BooBoo 200kg
Polar 100kh
It's an array containing an object, not an object. Anyway just get the first item of the array.
This should work:
Object.keys(bears[0]).map(key => <p>{`${key} ${bears[0][key]}`}</p>);
I think that the JSON object's structure itself is wrong.
It should be structured like this:
var bears = [{
name: "Yogi",
weight: "123kg"
}, {
name: "Pooh",
weight: "110kg"
}, {
name: "Grizly",
weight: "112kg"
}, {
name: "BooBoo",
weight: "200kg"
}]
Then you can go ahead and iterate through it using a for loop inside of the render() method like this.
render() {
var bearElements = [];
for (var bearIndex = 0; bearIndex < bears.length; bearIndex++) {
bearElements.push(
<p>{`${bears[bearElements].name}` `${bears[bearElements].weight}`}</p>
)
}
return (
<div>{bears}</div>
);
}

Categories