Search code examples
vuejs2vuex

Vue computed property changes store state


I am trying to build a simple filter which sorts an array in Vue. I have data in state, which is updated by api call which is only triggered while loading the page. Data structure is list of warehouses, each has id and other properties, period object, inside period object there is array of salesagents objects, each of salesagents has id.

Then in component there is an array of warehouses ids and array of salesagents ids. I change the contents of these arrays by clicking on checkboxes for warehouses or salesagents to be visible or not.

I have computedWarehouses computed property which runs when aforementioned visible salesagents or warehouses array is changed.

Warehouses part works fine, when I uncheck checkbox for the warehouse, warehouse is removed from the computedWarehouses array but the warehouse is still in state.data. When I click again on the checkbox warehouse is again inserted in the computedWarehouses array and everything is good.

Now when I try to do the same for salesagents which are inside of the warehouses period object then I can remove the salesagents from the computedwarehouses array but for some reason they get also removed from state data so unchecking a salesagents checkbox removes the salesagent from computedwarehouses array but checking the checkbox again has no effect because that salesagent is not in the data anymore.

data I get from state via a getter.

computedWarehouses() property code:

computedWarehouses() {
      let computedWarehouses = [];
      let intWarehousesFilter = this.warehousesFilter.map( (id) => {
        return parseInt(id);
      });

      for (let warehouse in this.data) {
        if (intWarehousesFilter.includes(this.data[warehouse].id)) {
          computedWarehouses.push(this.data[warehouse]);
        }
      }

      let intConsultantsFilter = this.consultantsFilter.map( (id) => {
        return parseInt(id);
      });
      
      for (let warehouse in computedWarehouses) {
        for (let workday in computedWarehouses[warehouse].period.workdaysObjects) {
          let computedSalesAgents = [];
          for (let salesAgent in computedWarehouses[warehouse].period.workdaysObjects[workday].salesAgents) {
            let salesAgentObject = computedWarehouses[warehouse].period.workdaysObjects[workday].salesAgents[salesAgent];
            if (intConsultantsFilter.includes(parseInt(salesAgentObject.id))) {
              computedSalesAgents.push(salesAgentObject);
            }
          }
          computedWarehouses[warehouse].period.workdaysObjects[workday].salesAgents = computedSalesAgents;
        }
      }

      return computedWarehouses;
},

What am I doing wrong? I do not want to change the state, I want that the state.data would remain the same all the time, so when I check again some salesagents checkbox I would see the agent again.


Solution

  • I will answer myself. The solution was to make a copy and break all ties to the original data.

    const tempWarehouses = JSON.parse(JSON.stringify(this.data));

    I added this line and did all my operations on tempWarehouses so the this.data was left untouched.