0

I am experiencing some strange behavior when trying to do the following:

  1. Create a base JSON object
  2. Create a for loop and send the base object to a new function to be modified
  3. The new function should modify one element of the base JSON object and then send it back

Here is my sample code:

var object = [
{"test": "Test1", "id": 0},
{"test": "Test2", "id": 0},
{"test": "Test3", "id": 0},
{"test": "Test4", "id": 0},
];


for(var i=0; i < 4; i++) {
newObject(i).then(function(obj){
  console.log(obj);
  })
}

function newObject(i) {
  return new Promise(function(resolve, reject){
  var newObject = object;
  newObject[i].id = i;
    resolve(newObject);
  })
}

What I would expect to receive back from console.log(obj) is 4 times a different object like this

[
   {"test": "Test1", "id": 0},
   {"test": "Test2", "id": 0},
   {"test": "Test3", "id": 0},
   {"test": "Test4", "id": 0},
];

[
   {"test": "Test1", "id": 0},
   {"test": "Test2", "id": 1},
   {"test": "Test3", "id": 0},
   {"test": "Test4", "id": 0},
];

[
   {"test": "Test1", "id": 0},
   {"test": "Test2", "id": 0},
   {"test": "Test3", "id": 2},
   {"test": "Test4", "id": 0},
];

[
   {"test": "Test1", "id": 0},
   {"test": "Test2", "id": 0},
   {"test": "Test3", "id": 3},
   {"test": "Test4", "id": 0},
];

However what I end up receiving is 4 times the exact same object like this

[
   {"test": "Test1", "id": 0},
   {"test": "Test2", "id": 1},
   {"test": "Test3", "id": 2},
   {"test": "Test4", "id": 3},
];
Riley MacDonald
  • 453
  • 1
  • 4
  • 15
  • 1
    A note: There is no such thing as a JSON object. – Tyler Roper Jan 12 '19 at 16:23
  • 1
    Also, `var newObject` isn't a *copy* of your initial object, it's a *reference* to it. You're changing the same single object with each and every loop. – Tyler Roper Jan 12 '19 at 16:28
  • 1
    See how to clone an array of object. https://stackoverflow.com/questions/597588/how-do-you-clone-an-array-of-objects-in-javascript – xwlee Jan 12 '19 at 16:31

1 Answers1

2

Your problem is that inside your Promise function, you're referencing the same objects, instead of creating clones.

var newObject = object; // this is a reference, not a copy/clone

Instead, you need to create a deep clone of the object array. One way of doing it in a one-liner is using JSON:

var newObject = JSON.parse(JSON.stringify(object));

A better way would be:

var newObject = object.map(({test, id}) => ({test, id}));

Mihai Potra
  • 838
  • 4
  • 6