'How to return state data from vuex action in components

I have an action that fetches data from my database, I assign the response from the request to various objects/variables in the state in my vuex store, this action is then dispatched in app.js

The code for that looks something like this:

store.js

actions: {
  getData(context) {
    axios.get('/getData').then(function(res) {
        context.state.var = res.data.SomeArray.var;
        context.state.var2 = res.data.SomeArray.var2;
      }
    );
  }
}

Dispatch the action and log to console the state and state data

app.js

const app = new Vue({
    el: '#app',
    store: store,
    async created() {
      await this.$store.dispatch('getData')
      console.log(this.$store.state)
      console.log(this.$store.state.var)
    }
});

When I print the state with console.log(this.$store.state) and console.log(this.$store.state.var), the correct objects with the appropriate values are logged. I then try to propagate the state data to various components.

The trouble is when I try to access individual objects/ variables from the state in my actual components. When I try console.log(this.$store.state.var) or even console.log(store.state.var), I get either undefined or some weird data that looks like this:

state data

This doesn't make any sense, since the state as a whole object clearly gets populated and is the correct data, but the individual objects that comprise the state are malformed?!

Am I referencing the data improperly, do I need to import the state from the file it's in?



Solution 1:[1]

Your mistake is that you are mutating the state using actions. You are supposed to only mutate state using mutations.

According to the Vuex documentation,

The only way to actually change state in a Vuex store is by committing a mutation

Below is an example of how it can be done

const store = new Vuex.Store({
  state: {
    var: {},
    var2: {},
  },
  mutations: {
    setVariables (state, payload) {
      // mutate state
      state.var = payload.var;
      state.var2 = payload.var2;
    }
  }
   actions:{
     getData(context){
      axios.get('/getData').then(function(res){
        context.commit('setVariables', res.data.SomeArray)
      });
     }
   }
})

Solution 2:[2]

For your issue with console.log, use Object.freeze() when you create your data object.

When a Vue instance is created, it adds all the properties found in its data object to Vue’s reactivity system. When the values of those properties change, the view will “react”, updating to match the new values.

The only exception to this being the use of Object.freeze(), which prevents existing properties from being changed, which also means the reactivity system can’t track changes.

https://vuejs.org/v2/guide/instance.html#Data-and-Methods

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tony
Solution 2