Search code examples
javascriptvue.jsvuex

Vuex - wait for api call and initial store before working with mapState data?


How do I wait / await for a slow-ish api call to finish and commit to store before doing something with the store object?

For example, in created() in App.js I do the below and if I don't wrap my transform functions in a timeout the data isn't committed yet and so they fail.

App.js

created: function () {
    this.$store.dispatch("loadData"); // loads all the data and commits to store as state.eventsData

    setTimeout(() => { // if I don't wrap these in a timeout, this.eventsData is not available for the functions
      this.transformDataForGrid(); // transforms eventsData and commits it as gridData
      this.transformDataForCalendar(); // transforms eventsData and commits it as calendarData
    }, 500);
  },
methods: {
  transformDataForGrid(){// lots of manipulations of eventsData then state.commit("gridData", newdata},
  transformDataForCalendar(){},// lots of manipulations of eventsData then state.commit("calendarData", newdata},
}


Solution

  • I figured this out. I created a Boolean store item called loading and initialized it as true in the beginning (page load). Also have a mutation called setLoading. In App.vue created(){} I dispatch an action to do the axios api call. In the .then of that, I commit the data to the store and also commit setLoading as false. Then, back in App.vue I mapState loading and "watch" loading so when it changes, I can fire off my tranformation functions.

    App.

      computed: mapState(["loading", "eventsData"]),
      watch: {
        loading() {
          if (!this.loading) { // when loading changes to false in store/index.js I fire off my functions
            this.transformDataForGrid();
            this.transformDataForCalendar();
          }
        },
      },
      created: function () {
        this.$store.dispatch("loadData"); // load data
      },
    methods: { 
      transformDataForGrid(){ // do stuff },
      transformDataForCalendar() { // do other stuff },
    
    }
    

    store/index.js

      mutations: {
        ... // other mutations
        setLoading(state, loading) {
          state.loading = loading;
        },
      },
      actions: {
        loadData({ commit }) {
          axios
            .get("/data/eventsData.json")
            .then((response) => {
              commit("setEventsData", response.data);
              commit("setGridData", response.data);
              commit("setCalendarData", response.data);
              commit("setLoading", false); // loading is done
            })
            .catch((error) => {
              console.log(error);
            });
        },
      },