1

I have created a component that allows users to select objects from a list and put them into another "selected list" lets say. So there are 100 items in the main list and however many in the users selected list. They can of course remove and add items as they want.

There are two buttons at the bottom of the modal. Cancel and Update. Where Cancel forgets anything they have added or removed (essentially an Undo of when they popped up the modal) and Update technically does nothing because when you are adding and removing, I am actually updating the real selected list.

So my data has these two properties (among others of course):

originalSelections: [],
selectedMedications: [],

There is a method that only gets called one time to set the selectedMedications property to whatever the current state of originalSelections is. I have a console.log to prove I am not running this method more than once and it NEVER gets hit again.

console.log('Post Initing');

let Selected = [];

for (let med of this.value.OtherNotFromEpic) {
  let match = this.otherMedications.find(x => { return x.value === med });

  if (match) {
    Selected.push(JSON.parse(JSON.stringify(match)));
    this.originalSelections.push(JSON.parse(JSON.stringify(match)));
    this.selectedMedications.push(JSON.parse(JSON.stringify(match)));
  }
}

I was baffled at why the selectedMedications was changing, so I added a watch to let me know if it was:

watch: {
  originalSelections(newValue) {
    console.log(' ** Original Selection Changed', this.init, newValue);
  },
},

The Cancel method is as follows:

cancel() {
  $('#' + this.modalID).modal('hide');
  console.log('Cancel: this.originalSelections', JSON.parse(JSON.stringify(this.originalSelections)));

  this.selectedMedications = this.originalSelections;

  this.$nextTick(() => {
    console.log('  Cancelled: this.selectedMedications', JSON.parse(JSON.stringify(this.selectedMedications)));
  });
},

You can see that I am setting selectedMedications to whatever it was originally.

The odd thing is... This WORKS 100% the first time I bring up the modal. So I pop up the modal, remove an item, cancel the modal and it brings back the item I removed. Perfect!

If I bring the modal up again, remove that same item or any other item, cancel the modal and that item stays removed and the watch is actually hit. I have NO other place in the code where originalMedications = … or originalMedications.push or even originalMedications.slice ever happen. And it is my understand that the JSON.parse(JSON.stringify(match)) code I use to set it is making a new object and not a reference in any way.

Another odd thing I have found is that if I refresh the page, open the modal, cancel out without doing any adding or removing. Then I bring up the modal again and try either add or remove, then cancel the modal, those items do not revert back to the originalMedications state because originalMedications is the same as selectedMedications. Aargh!

So HOW can a property get altered when I never do anything to it after the initial setting of it?

1 Answer 1

1

In the cancel method, when below direct assignment is done here after both data is referring to same (since its array). So any time after the first cancel both originalSelections and selectedMedications array would have same reference and hence same data.

this.selectedMedications = this.originalSelections;

instead better to use concat as below? This will create a copy of originalSelections and assign that to selectedMedications. So any operations on selectedMedications will not affect the originalSelections.

this.selectedMedications = [].concat(this.originalSelections);

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

3 Comments

Thank you very much. The answer is so obvious. Sometimes you just get too close to something and can't see through the code. Awesome!
I also like the shorter version to get a copy of an array. Do you know if there is a shorter way to copy an object than let someObject = JSON.parse(JSON.stringify(otherObject));?
Easy way for Object copy is below but both of those are ES6 way if that's not a problem for you. Using Spread operator: let someObject = {...otherObject} or using Object.assign: let someObject = Object.assign({}, otherObject)

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.