Search code examples
vue.jsvuex

Vue JS. Layered calls not synchronised: Web Page -> VUEX-> API call


I have refactored my VUE JS code to have a dedicated API layer (Calls out to AWS Graphql services), it is called by the VUEX layer. It now has the following levels:

     Web Page -> Vuex  -> API

I want to retrieve data (this.getActivities) before referencing it (Point 7). I have cut down the code for simplicity:

 async created() {
    console.log("Point 1")
    await this.getActivities();

  },
 mounted() {
    console.log("Point 7")
    // reference the data set by this.getActivities()
  },


  methods: {
    
    async getActivities() {
      // from DB
      console.log("Point 2")
     this.$store.dispatch('getAllActivities')  // vuex call

    },


VUEX DATA STORE

 actions: {

     async getAllActivities ({ commit }) {
      console.log("point 3")

      const activities = await queries.getActivities()
 
      console.log("point 6")
      commit('setActivities', activities)

    },


API
  async getActivities () {

    await API.graphql({
        query: listActivities
      }).then((response) => {

         console.log("Point 4")

      })
      
      console.log("Point 5")


    return activitiesList
  },

Prints the following: Point 1 Point 2 point 3 Point 7 Point 8 Point 4 Point 5 point 6

I presume I have misused the await/sync processes?

Thanks


Solution

  • Assuming that you need the list of activities in more than 1 component/route (otherwise why would you store this list in Vuex instead of the component itself ?!) you would normally do something like this:

    <template>
      <div>
        <ActivityItem v-for="act in ACTIVITY_LIST" :key="act.id" :activity="act" />
      </div>
    </template>
    
    <script>
    import ActivityItem from './components/ActivityItem';
    import { mapGetters, mapActions } from 'vuex';
    import { ACTIVITY_LIST, FETCH_ACTIVITIES } from './store/constants';
    
    export default
    {
      components:
      {
        ActivityItem,
      },
      computed:
      {
        ...mapGetters([ACTIVITY_LIST]),
      },
      created()
      {
        this[FECH_ACTIVITIES]();
      },
      methods:
      {
        ...mapActions([FETCH_ACTIVITIES])
      }
    }
    </script>
    
    // store/constants.js
    export const ACTIVITY_LIST = 'ACTIVITY_LIST';
    export const FETCH_ACTIVITIES = 'FETCH_ACTIVITIES';
    export const SET_ACTIVITIES = 'SET_ACTIVITIES';
    
    // store/index.js
    import Vue from 'vue';
    import Vuex from 'vuex';
    import { ACTIVITY_LIST, FETCH_ACTIVITIES, SET_ACTIVITIES } from './store/constants';
    import myAPI from './api';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store(
      {
        strict: process.env.NODE_ENV !== 'production',
        state()
        {
          return {
            activities: []
          };
        },
        getters:
        {
          [ACTIVITY_LIST](state)
          {
            return state.activities;
          }
        },
        mutations:
        {
          [SET_ACTIVITIES](state, value)
          {
            state.activities = value || [];
          }
        },
        actions:
        {
          [FETCH_ACTIVITIES]({ commit })
          {
            return myAPI.getActivities().then(response =>
            {
              commit(SET_ACTIVITIES, response.data.activitiesList);
              return response.data.activitiesList; // optional
            });
          }
        }
      });