Search code examples
javascriptrestvue.jsvuex

Vue + Vuex reactivity of dictionary object


I am using Vue + Vuex for managing state.

Lets have store:

state: {
  nodes: {}
},
actions: {
  loadNodes ({ commit }, parameter) {
     axios.get('http://URL' + '/nodes', {
        params: {
          name: parameter['name'],
          type: parameter['type']
        }
      }).then((response) => {
        commit('nodeActivity', { uid: parameter['uid'], res: response.data })
    })
  }
},
mutations: {
  nodeActivity (state, data: {uid, res}) {
    Vue.set(state.nodes, data.uid, data.res)
  }
},
getters: {
  getNodes: state => state.nodes
}

This is probably okey, in nodes there is a dictionary structure { id: data }

Now I have component with hook:

created () {
    this.$store.dispatch('nodeActivity', { uid: this.$props.uid, name: this.$props.namepar, type: this.$props.typepar })
  } 

So API call got some data and are asynchronous stored. It works. But I need get specific uid something like this.$store.getters.getNodes[0] that does not work but this.$store.getters.getNodes works properly so I think reactivity is okey thanks to Vue.set(..). Even if I use const tmp = this.$store.getters.getNodes (tmp contains whole dictionary) and then tmp2 = tmp[0], tmp2 is not reactive. I do not know why. I am starting with Vue so I appreciate tips how to change store design.


Solution

  • Well, I found a poor and probably out of design solution. I just have watcher for a variable that loads data from store, someting like const tmp = this.$store.getters.getNodes. When tmp changes, I can notify that and assign variable tmp2 = tmp[number] so the behaviour is reactive. I find this solution quite hacky.