VirtualLife
VirtualLife

Reputation: 402

Vue v-model doesn't update from form input after updating it from a rest call

Still learning Vue, but in short, after I do data = axiosAjaxResponse anything I type into a form field does not get updated in the v-model.

I have a manage page that passes my prop to the child page with a data structure like this.

data() {
  return {
     Data: [{
        port: [
           {
              "portId": 11, ..., 
              schedule: [{ "scheduleId":1, ...

Child page template

<b-row>
   all port data put into form fields
</b-row>

<b-row v-for="(schedule, index) in growData[0].port[rowIndex].schedules" :key="index">
   <b-col>
      <b-form-group label="Off Length" :label-for="'offLength' + index">
         <b-form-input :id="'offLength' + index" v-model="schedule.offLength" size="sm" trim></b-form-input>
      </b-form-group>
   </b-col>
</b-row>
<b-row>
   <b-col>
      <button v-on:click="addSchedule(rowIndex)">update</button>  
      <button v-on:click="updateData()">update</button>  
   </b-col>
</b-row>


The logic

addSchedule(portId){  //add another schedule row
   this.Data[0].port[portId].schedules.push({startDateTime: '2020-03-12T00:00:00'})
   this.$forceUpdate();
},

async updateData() {
    var _this= this;

    var d = this.Data[0].port[_this.rowIndex]
    const { data } = await _this.$http.put(
        'https://localhost:44374/api/Schedule', d, 
        {headers: {'Content-Type': 'application/json'}}
    )
    _this.growData[0].port[_this.rowIndex] = data  //THIS KILLS ALL INPUTS
    this.$forceUpdate();
}

Everything works technically. The v-model (parent/child and vue plugin) all look correct after clicking update. Problem is, anything I type into any of the text boxes now, does not update the v-model. If I refresh the page, everything is fine.

I have tried using just this instead of _this. I've trued passing the data via EventBus back to the parent and updating there. I've tried putting the data into a new object and setting it. Nothing seems to make a difference and there are no errors.

Upvotes: 1

Views: 2295

Answers (1)

David K. Hess
David K. Hess

Reputation: 17246

The array assignment is not able to be intercepted by Vue in order to catch it and notify watchers.

Use _this.$set(_this.growData[0].port, _this.rowIndex, data)

That will execute the array assignment and notify the watchers of that data.

You can also use Vue.set() which is the same thing.

More background on this general topic available here:

https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

Upvotes: 1

Related Questions