0
votes

My app uses

  • axios to fetch user information from a backend server
  • vuex to store users
  • vue-router to navigate on each user's page

In App.vue, the fetch is dispatched

export default {                                                                   
  name: 'app',                                                                     
  components: {                                                                    
    nav00                                                                          
  },                                                                               
  beforeCreate() {                                            
    this.$store.dispatch('fetchUsers')                               
  }                                                                                
}                                                                                  

In store.js, the users is an object with pk (primary key) to user information.

export default new Vuex.Store({                                                 
  state: {                                                                      
    users: {},     
  },
  getters: {
    userCount: state => {                                                       
      return Object.keys(state.users).length                                    
    } 
  },
  mutations: { 
    SET_USERS(state, users) { 
      // users should be backend response 
      console.log(users.length)                                                                   
      users.forEach(u => state.users[u.pk] = u) 
  actions: { 
    fetchUsers({commit}) { 
      Backend.getUsers()                                   
        .then(response => {                             
          commit('SET_USERS', response.data)                       
        })                                       
        .catch(error => {                        
          console.log("Cannot fetch users: ", error.response)                   
        }) 
})

Here Backend.getUsers() is an axios call.

In another component which map to /about in the vue-router, it simply displays userCount via the getter.

Now the behavior of the app depends on timing. If I visit / first and wait 2-3 seconds, then go to /about, the userCount is displayed correctly. However, if I visit /about directly, or visit / first and quickly navigate to /about, the userCount is 0. But in the console, it still shows the correct user count (from the log in SET_USERS).

What did I miss here? Shouldn't the store getter see the update in users and render the HTML display again?

1

1 Answers

0
votes

Since it's an object Vue can't detect the changes of the properties and it's even less reactive when it comes to computed properties.

Copied from https://vuex.vuejs.org/guide/mutations.html:

When adding new properties to an Object, you should either:

Use Vue.set(obj, 'newProp', 123), or

Replace that Object with a fresh one. For example, using the object spread syntax we can write it like this:

state.obj = { ...state.obj, newProp: 123 }