0

What is the best way/how can I update two Objects with the same set of values?

The only method I know of, is by setting each property of each object concurrently. As per example below. Below I am using a method to populate the Objects, by passing the values as parameter in the method.

PLEASE NOTE: the individual parameter I pass in the method (populateIndividualDetails(individual: SelectedMemberIndividualData)) consists of many parameters I do not need, and is not in the format I desire. Hence the use of a method to assign the properties.

Additional Note: Both Objects I wish to populate have the same parameters, and is in the exact same format. The Objects have nested parameters.

Perhaps one could copy the 1st Object after it has been populated? 🤔

Example:

model = {
    initials: '',
    name: '',
        address: {
           streetName: '',
           ...
        }
    ...
}

initialValues= {
    initials: '',
    name: '',
        address: {
           streetName: '',
           ...
        }
    ...
}

populateIndividualDetails(individual: SelectedMemberIndividualData) {
    this.model.initials = individual.initials;
    this.initialValue.initials = individual.initials;
    ...
}

2 Answers 2

1

Rather than populating model and initialValues with empty key-value pairs, you could instead consider making an array of the properties which you want to be set in both the model and initialValues objects. Inside of populateIndividualDetails() you can then loop over this array with a for loop, and grab each property from the passed in individual object which you can then set on your model and initialValues objects.

const desiredProps = ["a", "b", "d"]; // contains "initials", etc...
const model = {};
const initialValues = {};
function populateIndividualDetails(individual) {
    for(const prop of desiredProps) {
      model[prop] = individual[prop];
      initialValues[prop] = individual[prop];
    }
}

populateIndividualDetails({a: 1, b: 2, c: 3, d: 4}); // ignore "c" value
console.log(model);
console.log(initialValues);

EDIT If you need model and initialValues to be populated initially, then it might be better to create one and deep-clone the other (as you mentioned you can have nested object properties) and then use recursion to handle the nested objects:

const model = {a: '', b: {c: ''}, e: ''};
const initialValues = JSON.parse(JSON.stringify(model)); // deep-clone model, both are their own object references.
function populateIndividualDetails(o1, o2, individual) {
  Object.keys(o1).forEach(key => {
    if(Object(o1[key]) === o1[key])
      populateIndividualDetails(o1[key], o2[key], individual[key])
    else
      o1[key] = o2[key] = individual[key];
  });
}

populateIndividualDetails(model, initialValues, {a: 1, b: {c: 2, d: 3}, e: 4, f: 5}); // ignore "f" value
console.log(model);
console.log(initialValues);

Sign up to request clarification or add additional context in comments.

5 Comments

Awesome solution, thank you! My challenge is that 1) I am setting the initial Object values as empty strings, as this is my initial state of my form component, before it gets populated. 2) The Objects have nested properties, which adds multiple facets to the for loop. Any suggestions?
@onmyway I've editted my answer to use a recursive function to walk through your model/initialValue object's keys, which values are then taken from the provided individual object.
Love it! Thank you very much. Works like a charm ;)
Quick question; is this one of the methods for creating a deep copy const initialValues = JSON.parse(JSON.stringify(model)); ?
@onmyway yes, JSON.parse(JSON.stringify(model)) is a way to deep-clone an object
0

You can just destructurate and pick the properties of individual the following way:

function populateIndividualDetails({initials}: SelectedMemberIndividualData) {
    this.model.initials = initials;
    this.initialValue.initials = initials;
}

but if you have several properties you might want this but this will replace the entire model and initial value objects and they will point to the same object…

function populateIndividualDetails(individual: SelectedMemberIndividualData) {
    const {a, b, c} = individual;
    const copy = {a, b ,c}
    this.model= copy;
    this.initialValue= copy;
}

What you are probably looking for is to just add some properties to the existing model and initialValue objects

function populateIndividualDetails(individual: SelectedMemberIndividualData) {
    const {a, b, c} = individual;
    const propertiesToAdd = {a, b ,c}
    this.model= {...this.model, ...propertiesToAdd};
    this.initialValue= {...this.initialValue, ...propertiesToAdd};
}

Note:

anObject = {...anObject, ...anotherObject};// can be replaced with
Object.assign(anObject,anotherObject);

Using lodash you could also do this:

function getDefaultProperties(anObject: SelectedMemberIndividualData){
return _.pick(anObject, ['a','b','c'])
}

function populateIndividualDetails(individual: SelectedMemberIndividualData){
const defaultProperties = getDefaultProperties(individual);
[this.model, this.initialValue].forEach((value) => {
_.assign(value, defaultProperties);
})
}

2 Comments

Thank you for your response. I really like it! Will it work with nested Objects? I have updated my question 🤦‍♂️
the copy will only copy the first level of properties (it's a shallow, not deep copy). If you need to copy an entire object, use _.cloneDeepof lodash, or without lodash, if your object only holds json compliant values: const copy = JSON.parse(JSON.stringify(original))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.