Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS - Accessing store data inside mounted

Tags:

vue.js

vuejs2

I'm having trouble understanding the following:

I have a store which contains variables needed for the application. In particular, there is a globalCompanies which stores:

globalCompanies: {
   current: [],
   all: [],
   currentName: "",
}

Inside another component, I want to do the following:

mounted() {
   this.$store.dispatch( "fetchUsers" );

   var currentName = this.$store.state.globalCompanies.currentName; 

   console.log(currentName); 
},

However, this just shows as empty. I know the value is there because I have computed which returns the currentName and it works fine inside the view itself. It just doesn't like the fact that it's in the mounted component.

Where am I going wrong and what can I do to resolve this issue? I really need to capture the companies Name in order to use it for some real time events.

like image 285
Phorce Avatar asked Jun 02 '17 08:06

Phorce


2 Answers

As a result of our discussion:

In the question Vuex state value, accessed in component's mounted hook, returns empty value, because it is set in an async action which does not resolve before mounted executes.

When you need to trigger some function when async action in Vuex resolves with a value, you can achieve it using watch on a computed property, which returns a value from your Vuex state. When a value in store changes, the computed property reflects these changes and watch listener executes:

const store = new Vuex.Store({
  state: {
    globalCompanies: {
      test: null
    }
  },
  mutations: {
    setMe: (state, payload) => {
      state.globalCompanies.test = payload
    }
  },
  actions: {
    pretendFetch: ({commit}) => {
      setTimeout(() => {
        commit('setMe', 'My text is here!')
      }, 300)
    }
  }
})

new Vue({
  el: '#app',
  store,
  computed: {
    cp: function() { // computed property will be updated when async call resolves
      return this.$store.state.globalCompanies.test;
    }
  },
  watch: { // watch changes here
    cp: function(newValue, oldValue) {
      // apply your logic here, e.g. invoke your listener function
      console.log('was: ', oldValue, ' now: ', newValue)
    }
  },
  mounted() {
    this.$store.dispatch('pretendFetch');
    // console.log(this.cp, this.$store.state.globalCompanies.test); // null
    // var cn = this.$store.state.globalCompanies.test; // null
    // console.log(cn) // null
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.js"></script>
<script src="https://unpkg.com/[email protected]"></script>
<div id="app">
  {{ cp }}
</div>
like image 115
Egor Stambakio Avatar answered Oct 14 '22 10:10

Egor Stambakio


VueJS - Accessing Store Data Inside Mounted

Ran into this issue and it turned out to be a scope issue.

Store:

export default () => {
     items:[],
     globalCompanies:{
        current:[],
        all:[],
        currentName: "Something"
     },
     ok: "Here you go"
}

Getters:

export default {
   getGlobalCompanies(state){
      return state.globalCompanies;
   }
}

Mounted: This works...

mounted() {
   // Initialize inside mounted to ensure store is within scope
   const { getters } = this.$store; 

   const thisWorks = () => {
      const globalCompanies = getters.getGlobalCompanies;
   }
},

This is Bad: Reaching for the store outside the mounted scope

mounted() {
   function ThisDontWork() {
      const { getters } = this.$store; // this.$store == undefined
   }

   ThisDontWork();
},
like image 1
Jason Avatar answered Oct 14 '22 10:10

Jason