I have a Vue component which basically does the following things:
- When mounted, load some data from a remote API and initialize the Vue model with the response data.
- When submitting a form, some information need to be removed from the
userData
object which are only provided by the backend. - 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))
.