Search code examples
vue.jsvuejs2nuxt.jsvuexwatch

Vuejs/Nuxtjs watch is unable to watch for changes within the Array of Objects from Vuex Store


I am developing an application using Vuejs/Nuxtjs within this application I have a component IdentifiersNode.vue within that I would like to watch for a Vuex Store array identifiersArray.

I am able to watch the identifiersArray for direct changes such as push, direct key-value changes but when I add a new object to the object within the identifiersArray then watch would not work for some reason.

Following is the watch function in my IdentifiersNode.vue:

watch: {
    '$store.state.modules.identifiersInfoStore.identifiersArray': {
        handler (val) {
            console.log('WATCH : ' + JSON.stringify(val, null, 4))
        },
        deep: true
    }
},

Following are the changes happening to my identifiersArray within the Vuex Store Mutations present in identifiersInfoStore .js:

saveIdentifiersInfo (state, payload) {
    // Upon saving the Identifiers info save the information into respective object of identifiersArray
    const identifiersNode = state.identifiersArray.find(node => node.identifiersId === state.currentNodeId)

    console.log('NODE BEFORE : ' + JSON.stringify(identifiersNode, null, 4))
    
    identifiersNode.instanceData = payload.instanceData
    
    console.log('NODE ARRAY AFTER : ' + JSON.stringify(state.identifiersArray, null, 4))
},

As we can see I am adding an object to an existing object within the identifiersArray but when I do this I would expect my watch function to trigger in IdentifiersNode.vue as I have deep: true but for some reason, it does not work at all.

Can someone please tell me if it's possible to detect even a minute change to an array using the Vuex store and Vue watch? If not then what is an alternative that I can take?

Following is my identifiersNode from console.log:

NODE BEFORE : {
    "identifiersId": 1,
    "name": "identifiersNode1"
}

Following is the state.identifiersArray from console.log:

NODE ARRAY AFTER : [
    {
        "identifiersId": 1,
        "name": "identifiersNode1",
        "instanceData": {
            "name": "Batman",
            "job":"IT"
        }
    }
]

Solution

  • Providing the answer can be helpful to someone else in the future.

    I was actually appending the object to an existing object in Array within Vuex Store. Hence, the watch was not able to identify the change. I changed it to vue.set which worked for me.

    Previously I was using to append to my existing object:

    identifiersNode.instanceData = payload.instanceData
    

    Later I changed to:

    // Use the Vue reactive approach to add the instanceData object to existing object
    Vue.set(identifiersNode, 'instanceData', payload.instanceData)
    

    Following is my watch in Vue component, I used this code within my mounted can also be used within watch as well:

    // Watch for the changes on the identifiers array 
    this.$watch('$store.state.modules.identifiersInfoStore.identifiersArray', (val) => {
        console.log(JSON.stringify(val,null,4))
    }, { immediate: true, deep: true })