Home > database >  Vue does not update model after axios response
Vue does not update model after axios response

Time:09-21

I have a Vue component which basically does the following things:

  1. When mounted, load some data from a remote API and initialize the Vue model with the response data.
  2. When submitting a form, some information need to be removed from the userData object which are only provided by the backend.
  3. The response of the update will again contain the object which was deleted in #2.

The problem is: Although the reponse data are correct (response.data contains userData.someNestedObject), Vue does not update the view, i.e. this.userData.someNestedObject is not displayed. But I don't understand why.

data() {
  return {
    userData: {}
  }
}
async mounted() {
  const response = await ApiService.getUser();
  this.userData = response.data;
},
methods: {
  async submit() {
    // delete some object from userData which must not be included in the update request
    delete this.userData.someNestedObject;
    // update user and update data with response
    const response = await ApiSerivce.updateUser(this.userData);
    this.userData = response.data;
  }
}

CodePudding user response:

This happening because Vue did not wrap the userData object with reactive properties. To fix this you either have to fully describe userData in data like:

data() {
  return {
    userData: {
      someNestedObject: null
    }
  }
}

Or reassign entire userData object when deleting property Like:

methods: {
  async submit() {
    // delete some object from userData which must not be included in the update request
    const newUserData = this.userData;
    delete newUserData.someNestedObject;
    this.userData = newUserData;

    // update user and update data with response
    const response = await ApiSerivce.updateUser(this.userData);
    this.userData = response.data;
  }
}

CodePudding user response:

From the Vue documentation (https://vuejs.org/v2/guide/reactivity.html#For-Objects)

"Vue cannot detect property addition or deletion... a property must be present in the data object in order for Vue to convert it and make it reactive."

To add reactive properties to an object you have to use

Vue.set(vm.someObject, 'b', 2)

or

this.$set(this.someObject, 'b', 2)

Or you can use Object.assign to assign new properties to an new object with properties from the old object and the new object:

this.userData = Object.assign({}, this.userData, response.data);

CodePudding user response:

Finally, the answer by @ikkoo pointed me into the right direction. I needed to do a deep copy of the objects, so that all their properties and inner objects are copied as well.

I ended up using lodash's cloneDeep function which works and solves my issue:

this.userData = cloneDeep(response.data)

For simple objects you could also use JSON.parse(JSON.stringify(myObject)).

  • Related