1
votes

I've managed to break VueJS reactivity with my Vuex store thanks (I think) to a complex data model. The data is an object of arrays of objects as follows:

"users": { 
  "2017": [
    { id: 1, name: "bob" },
    { id: 2, name: "jane" },
  ],
  "2016": [ 
    ...
  ]
},
"dude": null

I had originally been storing ES6 classes in the store (I have a lot of helper functions) but have since removed that.

In order to access the right user I have a computed property as follows:

  computed: {
    user () {
      return this.$store.state.users.users[this.$store.state.users.currentDate][this.$store.state.users.currentUserIndex]
    },
    ...

The problem occurs when I commit a mutation to update the name (for example), I can see in the Chrome Vue debugger that the state has changed however the template has not (i.e. user.name continues to be the previous name).

Here is the code for the mutation:

  PATCH_USER (state, payload) {
    let index = state.users[state.currentDate].findIndex((el) => el.id === payload.user.id)
    let user = Object.assign(state.users[state.currentDate][index], payload.user)
    Vue.set(state.users[state.currentDate], index, user)
  },

Now, that part that makes me thing I'm doing something silly. If I add a computed property for dude (root level state item) and then include it in the template then the user name is correctly updated.

There is a lot more to the application but hopefully I'm doing something wrong with what I've shown.

Any help is much appreciated!

UPDATE

Figures after 8 hours of wrestling with this the answer seems to have come within 2 mins of posting to SO. (thanks @blockhead and @bert-evans).

I thought I had checked all of the code for this however it turns out the very first time data was loaded from the backend server it was wrong. payload is the response from the web API:

// bad 
SET_USERS (state, payload) {
  state.users[state.currentDate] = payload.users
}

// good
SET_USERS (state, payload) {
  Vue.set(state.users, state.currentDate, payload.users)
}
1
If you see the update in the vue dev tools right away, without having to refresh, that means it's already reactive.blockhead
How do you updated the user? Can we see the code?Bert

1 Answers

2
votes

The issue was indeed incorrectly assigning a new key to an existing Vuex object. The following code using Vue.set resolved the issue:

SET_USERS (state, payload) {
  // object, key, value
  Vue.set(state.users, state.currentDate, payload.users)
}