Vuex - When to load/initialize store data from http server

16,934

Solution 1

@Bert was right. I added the dispatch method to the created() method of my component.

export default {
    name: 'Menu',
    created() {
      this.$store.dispatch('fetchNodeInfo');
    },
...
}

Solution 2

Have a look at the vue.js lifecycle diagram here: https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram and read on the the lifecycle hooks here: https://vuejs.org/v2/guide/instance.html#Instance-Lifecycle-Hooks. It will hep you considerably in understanding when and where to add the stores dispatch method. this.$store.dispatch('fetchNodeInfo')

In Short:

  • Created hook: Instance has been created, all the data observation, computed properties, methods, watch/event callbacks have been set up but the $el property isn't available yet.

  • Mounted hook: Vue instance has been mounted, where el is replaced by the newly created vm.$el. el being the instance creation via new Vue({...}).

For your reading pleasure:

Share:
16,934

Related videos on Youtube

codepleb
Author by

codepleb

#frontend #pwa #angular #vuejs #nodejs #expressjs #playwright #cryptocurrency #blockchain #dag

Updated on September 15, 2022

Comments

  • codepleb
    codepleb over 1 year

    I want to show some data in the menu-bar, that needs to be fetched remotely (http get call) to be correctly displayed. When my application loads, the store wasn't initialized yet. Where should I do that?

    This is what I have right now. nodeInfo is an empty object, as long as no data is fetched.

    navigation component

    <template>
      <nav class="navbar" role="navigation" aria-label="main navigation">
        ...
          <div class="navbar-end">
            <span class="navbar-item">
              <div v-if="nodeInfo.latestSolidSubtangleMilestoneIndex">
                {{nodeInfo.latestSolidSubtangleMilestoneIndex}} / {{nodeInfo.latestMilestoneIndex}}
              </div>
              <div v-else>
                Node seems offline!
              </div>
            </span>
          </div>
        </div>
      </nav>
    </template>
    
    <script>
      import {mapGetters} from 'vuex';
    
      export default {
        name: 'Menu',
        computed: {
          ...mapGetters(['nodeInfo']) // Only the getters, no actions called to initialize them.
        }
      };
    </script>
    
    <style scoped>
    
    </style>
    

    store:

    import Vue from 'vue';
    import Vuex from 'vuex';
    
    Vue.use(Vuex);
    
    import axios from 'axios';
    
    const iri_ip = '192.168.1.199';
    const iri_port = '14265';
    
    const state = {
      token: null,
      loading: false,
      nodeInfo: {}
    };
    
    const mutations = {
      SET_NODE_INFO(state, info) {
        state.nodeInfo = info;
      }
    };
    
    const actions = {
      fetchNodeInfo({commit}) {
        axios(createIriRequest('getNodeInfo')).then(response => {
          console.log(response.data);
          commit('SET_NODE_INFO', response.data);
        });
      }
    };
    
    const getters = {
      token: state => state.token,
      loading: state => state.loading,
      nodeInfo: state => state.nodeInfo
    };
    
    const loginModule = {
      state,
      mutations,
      actions,
      getters
    };
    
    function createIriRequest(command) {
      return {
        url: `http://${iri_ip}:${iri_port}`,
        data: {'command': command},
        method: 'post',
        headers: {
          'Content-Type': 'application/json',
          'X-IOTA-API-Version': '1'
        }
      };
    }
    
    export default new Vuex.Store({
      modules: {
        loginModule
      }
    });
    

    The naming doesn't make much sense at the moment. But would I need to call the "actions" from the create() method of the menu component? That would somehow be weird. It would be cool if my store could somehow make the initial http calls itself without needing to be triggered. I don't even know how to call an action just like that from the create() part.

    • Bert
      Bert almost 6 years
      Once the store is created, you just need to use the dispatch method of the store, which you can use at any time. You could call it before your Vue is even created if you desired.
  • Endy Tjahjono
    Endy Tjahjono over 4 years
    My 2c: in my case initializing the store on mounted was too late in the process, so initializing on created was just the right solution.