1

Hi i am working with javascript/node.js. I have two data objects. (Please note that the real objects are much more complex than this.)

    const original = {
        'totAmount': 10,
        'testVal': 'zzzzzzzz',
        'potentialPaid': 10,
        'depositAmount': 10,
        'payment': {
            'amount': 10,
             'testVal': 'zzzzzzzz',
            'details': {
                'amount': 10,
                'testVal': 'zzzzzzzz',
                'statusHistory': {
                    'amount': 10,
                    'testVal': 'zzzzzzzz'
                }
            }
        },
        'coupon': {'test': 1000}
    };

and

const dataToUpdate = {
        'totAmount': 65,
        'potentialPaid': 65,
        'depositAmount': 65,
        'payment': {
            'amount': 65,
            'details': {
                'amount': 65,
                'statusHistory': {
                    'amount': 65
                }
            }
        },
        'coupon': {}
    };

I want replace all the values in original from dataToUpdate with the same keys .

My expected result is

    const original = {
        'totAmount': 65,
        'testVal': 'zzzzzzzz',
        'potentialPaid': 65,
        'depositAmount': 65,
        'payment': {
            'amount': 65,
            'testVal': 'zzzzzzzz',
            'details': {
                'amount': 65,
                 'testVal': 'zzzzzzzz',
                'statusHistory': {
                    'amount': 65,
                    'testVal': 'zzzzzzzzz
                }
            }
        },
        'coupon': {}
    };
  • All the values with the same keys in original object should be replaced by the other object values.

I was looking at various solutions like , Object.assign() .merge in lodash and many others.

I am stuck with this for more than 3 hours now and still i cannot find any solution .

Is there any Default javascript function there available doing this kind of a thing ? , please help.

Thanks in advance .

3
  • I think you are trying to merge two objects with two different criteria at the same time. What I mean is, you are trying to keep the original.payment.testVal in your result object and then you want to omit the original.coupon.test in the result object. So how would your helper function (Object.assign, _.merge, etc) know when you want to keep a field from the original object and when you don't? Commented Nov 2, 2017 at 4:57
  • mm i guess if the object is empty i want to replace and if the object is not empty i want to merge Commented Nov 2, 2017 at 5:01
  • 1
    I am not aware of a function (either native nor from a lib) than can help you achieve that because of the custom criteria you are applying. You will need to implement your own merge function if that is ok. Commented Nov 2, 2017 at 5:06

3 Answers 3

3

After a bit of research I found that since version 4.0.0 lodash has a mergeWith function that lets you apply a custom criteria for the merge.

I am adding here a jsfiddle that works for your example but that might need to be adjust a little to cover some other scenarios (I am not sure though).

The function from the jsfiddle that let you customize the merge criteria is this:

function customizer(objValue, srcValue) {
  if (_.isEmpty(srcValue)) {
    return srcValue;
  }
  else {
    _.merge(objValue, srcValue);
  }
}

And here is the jsfiddle:

http://jsfiddle.net/q9g2L60g/

I hope this helps.

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

Comments

1

Lodash's _.mergeWith() is recursive out of the box. _.mergeWith() accepts a customizer function. If the customizer returns undefined, _.mergeWith() uses it's default merging rules.

const original = {"totAmount":10,"testVal":"zzzzzzzz","potentialPaid":10,"depositAmount":10,"payment":{"amount":10,"testVal":"zzzzzzzz","details":{"amount":10,"testVal":"zzzzzzzz","statusHistory":{"amount":10,"testVal":"zzzzzzzz"}}},"coupon":{"test":1000}};
const dataToUpdate = {"totAmount":65,"potentialPaid":65,"depositAmount":65,"payment":{"amount":65,"details":{"amount":65,"statusHistory":{"amount":65}}},"coupon":{}};

const result = _.mergeWith(original, dataToUpdate, (objValue, srcValue) => _.isEmpty(srcValue) ? srcValue : undefined);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Comments

1

I made a custom function to replace nested properties in the object including array, object and date.

const a = {
  name: 'John Doe',
  email: '[email protected]',
  location: {
    country: {
      name: 'Japan',
      abbr: 'JP',
    },
    place: 'Tokyo',
  },
  phone: [123, 456],
  age: new Date('2021-05-15T15:28:37.453Z'),
};

const b = {
  email: '[email protected]',
  location: {
    country: {
      name: 'Canada',
      abbr: 'CA',
    },
  },
  phone: [123],
  age: new Date('2001-08-15T15:28:37.453Z'),
};

const superReplace = (object, value) => {
  let replace = {};

  Object.keys(object).forEach(prop => {
    if (value[prop] !== undefined) {
      if (Array.isArray(object[prop])) replace[prop] = value[prop];
      else if (value[prop] instanceof Date) {
        replace[prop] = value[prop];
      } else if (typeof object[prop] === 'object' && object[prop] !== null) {
        replace[prop] = superReplace(object[prop], value[prop]);
      } else replace[prop] = value[prop];
    } else replace[prop] = object[prop];
  });

  return replace;
};

console.log(superReplace(a, b));
// {
//   name: 'John Doe',
//   email: '[email protected]',
//   location: { country: { name: 'Canada', abbr: 'CA' }, place: 'Tokyo' },
//   phone: [ 123 ],
//   age: 2001-08-15T15:28:37.453Z
// }

Comments

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.