-1

I want to use Object.assign overwrite a nested object within an object.

for example if I have an object like

let obj = {2: {fruit: "orange", animal: "dog"} 3: {fruit: "apple", animal: "cat"}}

How would I use Object.assign to update for example the second object with key 3 to {fruit: "banana", animal: "pig"} but still maintain the structure of obj?

This solution should be dynamic so if for example the next time, the first object with key 2 could be updated to {fruit: "strawberry", animal: "bat"}

EDIT

So the new returned object will be

{2: {fruit: "orange", animal: "dog"} 3: {fruit: "banana", animal: "pig"}}

EDIT2

Solution needs to be dynamic

EDIT3

Seems as though this can't be achieved with just Object.assign so is there a deep copy solution to do this?

Celt67
  • 27
  • 4
  • 13
  • Are you using libraries like Lodash, jQuery or any other library for that matter? Those might have build-in helpers for this kind of deep merging of objects. – 3limin4t0r Mar 20 '20 at 14:01
  • No I'm not using any libraries. – Celt67 Mar 20 '20 at 14:28
  • `obj[3] = {fruit: "banana", animal: "pig"}; return obj` ... i don't understand the problem? – Ja͢ck Mar 20 '20 at 14:43
  • Does this answer your question? [How to deep merge instead of shallow merge?](https://stackoverflow.com/questions/27936772/how-to-deep-merge-instead-of-shallow-merge) – 3limin4t0r Mar 20 '20 at 14:47

2 Answers2

0

First thing to do is not call your object "Object":

let obj = {2: {fruit: "orange", animal: "dog"} 3: {fruit: "apple", animal: "cat"}};

Then you can use Object.assign() on obj[3]:

Object.assign(obj[3], {fruit: "banana", animal: "pig"});

(If you use "Object" as a variable name, you lose access to the global "Object", making Object.assign impossible to use.)

If you want a whole new object, you'll have to make copies of the nested objects because Object.assign() performs a shallow copy only. In your case that's pretty easy, but in general making a deep copy can be very complicated:

let newObj = {
  2: Object.assign({}, obj[2]),
  3: {fruit: "banana", animal: "pig"}
};
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • This isn't what I meant but my fault for not making it clear. I want to return a new object with both objects 2 and 3 still in the new object but have object 3 with new values. So this will be the returned object `{2: {fruit: "orange", animal: "dog"} 3: {fruit: "banana", animal: "pig"}};` – Celt67 Mar 20 '20 at 13:26
  • 1
    @Celt67 easy to do, I'll modify the answer – Pointy Mar 20 '20 at 13:32
  • This still doesn't answer the question. I created an easy example so that it would be easy for other people to understand. Your solution isn't dynamic because what if the next time object `3` needs to be over-ridden and values are {fruit: "pear", animal: "bat"}? Or if I wanted to update object `2` the next time – Celt67 Mar 20 '20 at 13:51
  • @Celt67 Your example mentions nothing whatsoever about anything being "dynamic". In the general case, what you seem to be asking for is a "deep copy" mechanism, and that gets very complicated. JavaScript has no built-in deep copy, just things like `Object.assign()` and spread syntax for making shallow copies. – Pointy Mar 20 '20 at 13:55
  • Yeah, my question was very unclear but I thought it was thing you could do by manipulating the `Object.assign` function, just didn't exactly know how. Sounds like you're saying it can't be done using just `Object.assign`. Would it be possible to do up a solution of the deep copy mechanism using this example? – Celt67 Mar 20 '20 at 14:09
0

Try this below:

let data = {2: {fruit: "orange", animal: "dog"} 3: {fruit: "apple", animal: "cat"}}

Object.assign(data[3], {fruit: "banana", animal: "pig"});

console.log(data)
Abhishek Kulkarni
  • 1,747
  • 1
  • 6
  • 8
  • I want the returned object to look like this `{2: {fruit: "orange", animal: "dog"} 3: {fruit: "banana", animal: "pig"}` Apologies, I didn't make that clear in the question. – Celt67 Mar 20 '20 at 13:31