3

For example, I want to access old data from watch properties in Vue.js. This is my example :

mounted(){
   axios.get(url).then(({data})=>{
     this.data = data //Initialize data to HTML. For example, username='A'
     Object.assign(this.oldValues, {data : data}) //Copying data to OldValues. Both object it should has same value
   })
},
data(){
  return {
    data : //data from mounted()
    oldValues : //Copied from data
  }
},
watch : {
  data : {
    handler : function(after, before){
       console.log(this.data) // show updated value 
       console.log(this.oldValues) // Expect : show copied value from first mounted()
    }
  }
}

When I edited the data using v-model="data" it triggers watch property successfully and showing a log like this.

<input v-model="data.username"> // 'AAA' 

Log shown :

data.username = 'AAA' //From this.data
data.username = 'AAA' //From this.oldValues. Expect, keep show the first data. It should username = 'A'

So, any help?

Ade Firman Fauzi
  • 377
  • 3
  • 15

2 Answers2

2

This case should be using Deep clone method. There's any 2 way to do this.

1. Lodash or Similiar library

this.oldValues = _.cloneDeep({data : data})

2. JSON.Parse + JSON.stringify

this.oldValues = JSON.parse(JSON.stringify({data : data})
Reference
Ade Firman Fauzi
  • 377
  • 3
  • 15
1

With Object.assign(this.oldValues, {data : data}) the oldValues is just a reference to the data. In this case the oldValues will updated when the data is changed.

With the following example you will get a real copy from data:

this.oldValues = Object.assign({}, this.oldValues, {data : data})

In JavaScript objects are a reference type.

Learn more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Comparing_Objects

Peter Kota
  • 8,048
  • 5
  • 25
  • 51
  • Sorry, I was marked done before. But actually, this way still won't work. I got a reference for why this happens and `Object.assign` is still copied as reference. https://github.com/vuejs/vue/issues/971 It works when I'm using lodash `deepClone`. But, I'm still finding another way without lodash. If you had another answer, I'd glad to check it. Thanks – Ade Firman Fauzi Aug 15 '18 at 15:03