Search code examples
arraysvuexstore

How to update object in vuex store array?


I'm pretty new to vue/vuex/vuetify but starting to get the hang of it. I have a problem though I haven't been able to solve properly.

I have an array of "projects" in my store. When deleting and adding items to the store via mutations the changes reflect properly in subcomponents referencing the array as a property.

However, changes to items in the array does not reflect even though I can see that the array in the store is updated.

The only way I got it to "work" with an update action was to either :

  1. remove the project from the array in the store and then add it
  2. use code that sort of does exactly the same as described above but like so:

    state.categories = [
    ...state.categories.filter(element => element.id !== id),
    category
    ]
    

But the problem with the above two methods is that the order of the array gets changed and I would really like to avoid that..

So basically, how would I rewrite my mutation method below to make the state reflect to subcomponents and keep the order of the array?

 updateProject(state, project) {

        var index = state.projects.findIndex(function (item, i) {
            return item.id === project.id;
        });

        state.projects[index] = project;
    }

Solution

  • You can use slice to inject edited project in correct position:

    updateProject(state, project) {
    
      var index = state.projects.findIndex(function(item, i) {
        return item.id === project.id;
      });
    
      state.projects = [
        ...state.projects.slice(0, index),
        project,
        ...state.projects.slice(index + 1)
      ]
    }
    

    or you can use JSON.parse(JSON.stringify()) to make a deep copy of object

    updateProject(state, project) {
    
      var index = state.projects.findIndex(function(item, i) {
        return item.id === project.id;
      });
    
      state.projects[index] = project;
      state.projects = JSON.parse(JSON.stringify(state.projects))
    }