Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating getter value Vuex store when state changes

I'm trying to figure out how to properly update a getter value when some other variable from VueX changes/updates. Currently I'm using this way in a component to update:

watch: {
   dates () {
     this.$set(this.linedata[0].chartOptions.xAxis,"categories",this.dates)
   }
}

So my getter linedata should be updated with dates value whenever dates changes. dates is state variable from VueX store. The thing is with this method the value won't be properly updated when I changed route/go to different components. So I think it's better to do this kind of thing using the VueX store.

dates is updated with an API call, so I use an action to update it. So the question is how can I do such an update from the VueX store?

EDIT:

I tried moving this to VueX:

async loadData({ commit }) {
      let response = await Api().get("/cpu");
      commit("SET_DATA", {
       this.linedata[0].chartOptions.xAxis,"categories": response.data.dates1,
this.linedata[1].chartOptions.xAxis,"categories": response.data.dates2
      });
    }

 SET_DATA(state, payload) {
      state = Object.assign(state, payload);
    }

But the above does not work, as I cannot set nested object in action this way...

like image 616
Alex T Avatar asked Mar 11 '20 13:03

Alex T


People also ask

How do I change my Vuex store value?

Vuex stores are reactive. When Vue components retrieve state from it, they will reactively and efficiently update if the store's state changes. You cannot directly mutate the store's state. The only way to change a store's state is by explicitly committing mutations.

Are the results of Vuex getter cached?

Vuex allows us to define "getters" in the store. You can think of them as computed properties for stores. As of Vue 3.0, the getter's result is not cached as the computed property does.

Is Vuex commit synchronous?

In Vuex, mutations are synchronous transactions: store. commit('increment') // any state change that the "increment" mutation may cause // should be done at this moment. To handle asynchronous operations, let's introduce Actions.

What is strict mode in Vuex?

Strict mode runs a synchronous deep watcher on the state tree for detecting inappropriate mutations, and it can be quite expensive when you make large amount of mutations to the state. Make sure to turn it off in production to avoid the performance cost.


1 Answers

Getters are generally for getting, not setting. They are like computed for Vuex, which return calculated data. They update automatically when reactive contents change. So it's probably best to rethink the design so that only state needs to be updated. Either way, Vuex should be updated only with actions/mutations

Given your example and the info from all your comments, using linedata as state, your action and mutation would look something like this:

actions: {
  async loadData({ commit }) {
    let response = await Api().get("/cpu");
    commit('SET_DATA', response.data.dates);
  }
}
mutations: {
  SET_DATA(state, dates) {
    Vue.set(state.linedata[0].chartOptions.xAxis, 'categories', dates[0]);
    Vue.set(state.linedata[1].chartOptions.xAxis, 'categories', dates[1]);
  }
}

Which you could call, in the component for example, like:

this.$store.dispatch('loadData');

Using Vue.set is necessary for change detection in this case and requires the following import:

import Vue from 'vue';

Theoretically, there should be a better way to design your backend API so that you can just set state.linedata = payload in the mutation, but this will work with what you have.

like image 149
Dan Avatar answered Oct 13 '22 20:10

Dan