Reputation: 1026
Let's say I have an object user like this.
const user = {
nationality: 'Italian',
age: 24,
name: {
firstName: 'rocky',
lastName: 'balboa',
},
};
I updated the firstName
item in the name
. I wanna convey this change to some function so it can also update the firstName in it's own user object with same structure too. What's the best way to do that ?
As per my understandings, to specify firstName, we would use user[name][firstName]
. But how do I send this to another object, let's say primeUsers
so it can update itself too ?
const primeUser = {
nationality: 'Italian',
age: 24,
name: {
firstName: 'rocky',
lastName: 'balboa',
},
};
One way would be to send an array of the "levels". So i'll send an array
const levels = ["name", "firstName"];
But i'm not sure how i'll use this to update the firstName
in primeUser
? I'm sorry it seems weird and i'm not explaining it very clearly. Hope you understand what i'm trying to achieve :)
Upvotes: 0
Views: 56
Reputation: 386570
You could iterate all properties and update the different values.
It works for any same structure of source and target object. If a found property is an iterable object, then a recursive function call is made with the actual property of source and target object.
function update(source, target) {
Object.keys(source).forEach(function (k) {
if (source[k] && typeof source[k] === 'object') {
update(source[k], target[k]);
return;
}
if (target[k] !== source[k]) {
target[k] = source[k];
}
});
}
const user = { nationality: 'Italian', age: 24, name: { firstName: 'rocky', lastName: 'foo' } };
const primeUser = { nationality: 'Italian', age: 24, name: { firstName: 'rocky', lastName: 'balboa' } };
update(user, primeUser);
console.log(primeUser);
.as-console-wrapper { max-height: 100% !important; top: 0; }
With generator of empty objects as well.
function update(source, target) {
Object.keys(source).forEach(function (k) {
if (source[k] && typeof source[k] === 'object') {
update(source[k], target[k] = target[k] || {});
return;
}
if (target[k] !== source[k]) {
target[k] = source[k];
}
});
}
const user = { nationality: 'Italian', age: 24, name: { firstName: 'rocky', lastName: 'balboa' } };
const primeUser = { };
update(user, primeUser);
console.log(primeUser);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 92854
Use Javascript getter/setter functions:
The get syntax binds an object property to a function that will be called when that property is looked up.
The set syntax binds an object property to a function to be called when there is an attempt to set that property.
const primeUser = {
nationality: 'Italian',
age: 24,
name: {
get firstName() {
return this._firstName;
},
set firstName(fName) {
this._firstName = fName;
},
lastName: 'balboa',
},
};
const user = {
nationality: 'Italian',
age: 24,
name: {
get firstName() {
return this._firstName;
},
set firstName(fName) {
this._firstName = fName;
primeUser.name.firstName = fName;
},
lastName: 'balboa',
},
};
user.name.firstName = 'rocky';
console.log(primeUser.name.firstName);
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set
Upvotes: 1
Reputation: 68393
I wanna convey this change to some function so it can also update the firstName in it's own user object with same structure too
You can define a setter on the firstName
property and pass the setter function as your own which will be invoked everytime this property changes
Demo
const user = {
nationality: 'Italian',
age: 24,
name: {
firstName: 'rocky',
lastName: 'balboa',
},
};
function yourFunction(val) {console.log("value set ",val)}
Object.defineProperty(user.name, "firstName" ,{set: yourFunction});
user.name.firstName = 1
Upvotes: 1