Ateev Chopra
Ateev Chopra

Reputation: 1026

How to specify the location of an item in an object

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

Answers (3)

Nina Scholz
Nina Scholz

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

RomanPerekhrest
RomanPerekhrest

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

gurvinder372
gurvinder372

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

Related Questions