Im struggling to find the right equilibrium between creating default properties of an object and keeping them 'reactive'. Important note I am using Vuex for my store.
I already checked: https://v2.vuejs.org/v2/guide/reactivity.html
However this does not seem to answer my question completely.
To give an good example of my problem:
In my 'store' I have products (json), containing contacts. Inside my application at some point new contacts are added to a product. For this I have an action.
const actions = {
addContact: ({ commit }, payload) => {
commit('ADD_CONTACT', payload)
}
}
Which calls a mutation.
const mutations = {
'ADD_CONTACT' (state, payload) {
var contact = {'id': payload.contact.contactId, 'gender': payload.contact.gender, 'firstName': payload.contact.firstName, 'initials': payload.contact.initials, 'lastName': payload.contact.lastName, 'middleName': payload.contact.middleName, 'birthDay': payload.contact.birthDay, 'childern': []}
state.products.find(function (product) {
if (product.id === payload.product_id) {
if (product.contacts) {
product.contacts.push(contact)
} else {
Vue.set(product, 'contacts', [])
product.contacts.push(contact)
}
}
})
}
}
As you can see I check if the product has an array of contacts, if it has not I create the array. Is this the correct way? Or does it make more sense to create an empty array in the first place, for example when adding a contact by defining an empty array 'childern'.
var contact = {'id': payload.contact.contactId, 'childern': []}
Thanks!
Short answer: yes, you need to mention the properties in the state beforehand. Adding them later will surely add the property but it won't be reactive.
var contact = {'id': payload.contact.contactId, 'childern': []}
Is the way to go.
Somewhere in the link you posted
Due to the limitations of modern JavaScript (and the abandonment of Object.observe), Vue cannot detect property addition or deletion. Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.
The same applies for vuex stores.
Just for reference I once wanted to set my store to its default state so did something like this:
// someModule.js Don't copy this, this doesn't set to default state.
const state = {
testProps: {
prop1: [],
prop2: null
}
}
const defaultState = {
testProps: {
prop1: [],
prop2: null
}
}
const mutations = {
mutationToSetState: (state, payload) => {
state.testProps = payload
},
mutationToResetState: (state) => {
state = defaultState // Please don't do this ever
}
}
Here I expected the state to change, which indeed happened but at the same time it lost its reactivity. So suddenly no change detection for everything that depended on this state.