Dhiraj Wakchaure
Dhiraj Wakchaure

Reputation: 2716

Delay in data/model update in Vue Js

I have created an example which is similar to my current work.

var App  = new Vue({
  el:'#app',
  data:{
    demoText:'text',
    sections:2,
    sectionData:[0,0]
  },
  methods:{
    changeData:function(){
      for(var i=0;i<this.sections;i++){
        if(isNaN(this.sectionData[i]))
          this.sectionData[i]=0;
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>

<div id='app'>
  
  <div v-for="n in sections">
    <input type="text" v-model=sectionData[n-1]>
  </div>
  
  <input type="button" @click="changeData" value="click">
</div>

In this example, when I click on the button I check if data is isNaN and change it to zero if it is. But this updated data doesn't update in DOM/textbox immediately. After that, if I update in another textbox then pending update action happens.

How can I resolve this issue?

Upvotes: 1

Views: 2361

Answers (1)

Bert
Bert

Reputation: 82489

There are a couple of issues in play here.

First is that Vue cannot detect the change you are making in your click handler when you change it by index. This is a common caveat when modifying an array in Vue.

Second, there is a bug in the code where if you blank out a text box, isNaN("") will resolve to false. This is documented in a number of places. I've implemented a very naive fix for this in the code below, but you should search for a stronger solution.

var App  = new Vue({
  el:'#app',
  data:{
    demoText:'text',
    sections:2,
    sectionData:[0,0]
  },
  methods:{
    changeData:function(){
      this.sectionData = this.sectionData.map(d => isNaN(parseInt(d,10)) ? 0 : d)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>

<div id='app'>
  
  <div v-for="n in sections">
    <input type="text" v-model=sectionData[n-1]>
  </div>
  
  <input type="button" @click="changeData" value="click">
</div>

Another alternative implementation of your click handler would be

for (let i=0; i < this.sectionData.length; i++)
  if (isNaN(parseInt(this.sectionData[i],10)))
    this.sectionData.splice(i, 1, 0)

Upvotes: 1

Related Questions