2

Here is a simplified version of my current setup.

When running this code you'll notice that modifying the changes array also manipulates the original referrals array. Is this because I'm pushing to the changes array inside a map function? How can I modify the changes array without modifying the referrals array?

var referrals = [
  {
    id: 1,
    name: 'John',
    change: true
  },
  {
    id: 2,
    name: 'Sally',
    change: false
  },
  {
    id: 3,
    name: 'Kim',
    change: true
  }
];

var changes = [];

var process = referrals.map(function(referral) {
  return new Promise(function(resolve, reject) {
    if (referral.change) {
      changes.push(referral);
    }
    resolve();
  });
});

Promise.all(process).then(function() {
  console.log('referrals before:', referrals);
  changes = changes.map(function(change) {
    change.change_id = change.id;
    delete change.id;
    return change;
  });

  console.log('changes:', changes);
  console.log('referrals after:', referrals);
});

3
  • 3
    You're not changing the referrals Array. You're changing the Objects it contains. And you'll have the same results without using Promises. When you push your Objects into the changes Array, you're actually pushing references to the Objects that are in the referrals Array. Not copies of them, which is what you seem to think. So then, when you change a property of these Objects, these differences will show everywhere these Objects are referenced. To solve this, look up "JS clone Object" Commented Aug 16, 2017 at 19:53
  • WTH are you using promises at all? There's nothing asynchronous in your code. Commented Aug 16, 2017 at 21:11
  • @Bergi I need a promise in my actual code because I'm going some requests between each object. I slimmed down my posted example. Commented Aug 16, 2017 at 21:42

2 Answers 2

3

You just need to create a deep copy of the inner objects, you can do it with lodash deepClone, or spread operator.

Something like that:

var referrals = [
{
  id: 1,
  name: 'John',
  change: true
},
{
  id: 2,
  name: 'Sally',
  change: false
},
{
  id: 3,
  name: 'Kim',
  change: true
}
];

var changes = [];

var process = referrals.map(function(referral) {
  return new Promise(function(resolve, reject) {
    if (referral.change) {
      changes.push({...referral}); // You will create a copy here.
    }
    resolve();
  });
});

Promise.all(process).then(function() {
  console.log('referrals before:', referrals);
  changes = changes.map(function(change) {
  change.change_id = change.id;
  delete change.id;
  return change;
});

console.log('changes:', changes);
console.log('referrals after:', referrals);
});
Sign up to request clarification or add additional context in comments.

Comments

1

Thanks blex for walking me through what was going on here. Essentially when I was pushing the object to a new array, I was pushing the entire reference and not just a copy. Using Object.assign to clone the object solves my issue.

Here is the entire edit for reference:

var referrals = [
  {
    id: 1,
    name: 'John',
    change: true
  },
  {
    id: 2,
    name: 'Sally',
    change: false
  },
  {
    id: 3,
    name: 'Kim',
    change: true
  }
];

var changes = [];

var process = referrals.map(function(referral) {
  new Promise(function(resolve, reject) {
    if (referral.change) {
      changes.push(Object.assign({}, referral));
    }
    resolve();
  });
});

Promise.all(process).then(function() {
  console.log('referrals before:', referrals);
  changes = changes.map(function(change) {
    change.change_id = change.id;
    delete change.id;
    return change;
  });

  console.log('changes:', changes);
  console.log('referrals after:', referrals);
});

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.