Search code examples
vue.jsaxiosvuexflux

Fetch data from endpoint using vuex action and set store variables in vuex?


I need to get data from an endpoint, and then assign the data to state variables in the store.

The code looks something like this.

import Vue from 'vue'
import axios from 'axios'

import Vuex from 'vuex'
Vue.use(Vuex)

export const store = new Vuex.Store({
    state: {
      sample: 'foo',
      sample2 : [],
      sample3: []
    },
    getters:{
    },
    actions:{
      getData(context){
        axios.get('/endpoint').then(function(response){
          console.log(context.state);
          console.log(context.state.sample);
          console.log(response);
          context.state.sample = 'bar';
          console.log(context.state.sample);
          context.state.sample2 = response.data.sample2data;
          context.state.sample3 = response.data.sample3data;
        }
        );
      }
    },
    mutations:{
    }
});

The trouble is the application doesn't execute the axios request at all, as far as I can tell. I've tested the endpoint elsewhere and I'm certain there's nothing wrong with the request itself. Surely, everytime my application is mounted the request should be executed?


Solution

  • You need to dispatch the action in the created method, where you create your vue instance. If the action is dispatched in a component, the store is only injected after the component is mounted. The data will only load after mounting the component which means component(s) that need to read the data, will have access to it, however the data in the state will be undefined on load.

    export const store = new Vuex.Store({
        state: {
          sample2 : [], // undefined
          sample3: []  // undefined
        },
        getters:{
        },
        actions:{
          getData(context){
            axios.get('/endpoint').then(function(response){
              context.state.sample2 = response.data.sample2data;
              context.state.sample3 = response.data.sample3data;
            }
            );
          }
        },
        mutations:{
        }
    });
    

    The below ensures that action is dispatched before mounting any components, and therefore the components will be able to read the state after the action has properly set the values

    import {store} from 'path/to/store/';
    
    new Vue({
      el: '#app',
      computed:,
      store: store,
      created() {
        this.$store.dispatch('getData') // dispatch loading
      }
    })