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

Viewed 579

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},
}

1 Answers

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);
        });
    },
  },
Related