Vue filter and the "Do not mutate vuex store state outside mutation handlers"

kojot picture kojot · Dec 27, 2017 · Viewed 9.9k times · Source

I'm still learning Vue and I can't understand why this error occurs.

Error: [vuex] Do not mutate vuex store state outside mutation handlers.

Here is my code:

https://jsfiddle.net/9sn78n1h/2/

I can't use my filter in the component, because the property name can be different. In the example above it's startDate, but in other data it could be addDate, endDate etc. In the vuex store I need the startDate in the format as it is, I don't want to mutate it. I'm not sure that writing another getter in the vuex like allProjectsWithFormatedDate is a good practice, but even so, it still yells about the mutating store.

So I create a local variable project in my computed method formattedProjects() and I don't know why I've got this error after changing it's value.

Can somebody help me to understand it and show the correct way to solve this problem?

I know I can set the strict mode to false to mute this error (and I should in production), but I belive there is a better way to solve this.

Answer

aks picture aks · Dec 27, 2017

The issue is what the error message says. Vuex has unidirectional flow, which you must be aware about. Any changes to the state must be done only in the mutations section. So by mistake we are mutating the object on the line below.

project.startDate = this.$options.filters.formatDate(project.startDate);

this will add/update(mutate) the startDate property on a store item project. This is the root cause of the problem. I think Vuex must have a better way to handle this. If you want to handle it in your computed property itself, it can be done like this.

formattedProjects() {
  var clonedProject = []
  var project = store.getters.allProjects;
  project.forEach(project => {
    clonedProject.push({
      ...project,
      startData: this.$options.filters.formatDate(project.startDate)
    })
  });
  return clonedProject;
}

Here is a link to the fiddle