Making new object property reactive in Vue.js

The link given below shows us the example of using mutations and actions and Vuex store
https://www.telerik.com/blogs/so-what-actually-is-vue-set for simpler examples if you are not sure what they are.

Problem: We have a “databases” array which is updated via mutation and accessed via calling a “getters” in a computed property of a component. Since the original databases object is an array with only one property named “name” hence when a new property named “tables” is added inside a mutation, the tables property is non-reactive and hence the databases object in component does not receive tables property with the list of tables in it.
We can make it reactive in two different ways.

1. Vue.set(object, property, newValue)
Since we are setting database tables within a loop it goes like this.

export default {
  state: {
    databases: []
  },
  mutations: {
    setDB(state, payload) {
      for(var i=0;i<state.databases.length;i++) {
        if(payload.dbname===state.databases[i].name)  {
          state.databases[i].tables = payload.data.tables
          Vue.set(state.databases[i], state.databases[i].tables, payload.data.tables)
        }
      }
    },
    setDatabases(state, databases)  {
      state.databases = databases
    }
  }
}

2. Setting tables property in a mutation which is triggered before setDB mutation

So the changed code in setDatabases would be as following. Please note that setDatabases is called before calling setDB mutation so when setDB is called it has databases object with tables property already added hence making it reactive.

setDatabases(state, databases)  {
  databases[0].tables = [] //initializing tables property for first element, it works for all later one.
  state.databases = databases
}

Then simply updating tables property as before without needing to call Vue.set.

setDB(state, payload) {
  for(var i=0;i<state.databases.length;i++) {
    if(payload.dbname===state.databases[i].name)  {
      state.databases[i].tables = payload.data.tables
    }
  }
}

Leave a Reply