Search code examples
vue.jsvuexresponse

VUEX Response of Dispatch VUE


How can I catch the response of a vuex dispatch from another component? So in case the response, for example, is 200 I do something else. component.vue

this.$store.dispatch("setTrigger");

store.js


    setTrigger({ state }) {
      axios
        .post(
          "https://xxx.us/api/savetriggers",
          {
            organizationsDefaultTriggerTime: state.organizationsDefaultTriggerTime,
            runFailedDefaultTriggerTime: state.runFailedDefaultTriggerTime,
          },
          {
            headers: {
              Authorization: `Bearer ${state.currentAuthToken}`,
            },
          }
        )
        .then((response) => {
          console.log(response.data);
        })
        .catch((error) => {
          console.log(error.data);
        });
    },

The setTrigger is in the store.js and I call dispatch from within a component.

Should I use states and getters also ? Is this the best practice?


Solution

  • you need to forward a promise from actions. that's kinda looks like this:

    main.js (Store)

    import Vue from "vue";
    import App from "./App.vue";
    import Vuex from "vuex";
    
    Vue.config.productionTip = false;
    
    Vue.use(Vuex);
    
    const store = new Vuex.Store({
      state: {
        something: 0
      },
      getters: {
        getSomething: (state) => state.something
      },
      actions: {
        doSomethingAction: async ({ getters }) => {
          return await new Promise((resolve) => {
            // we return the promise to resolve it inside the component
            setTimeout(() => {
              return resolve(getters.getSomething);
            }, 1000);
          });
        }
      },
      mutations: {
        updateSomething(state) {
          state.something = 1;
        }
      }
    });
    
    new Vue({
      store,
      render: (h) => h(App)
    }).$mount("#app");
    
    

    your component

    <template>
      <div id="app">
        <button @click="doSomethingInsideComponent">Do Something</button>
        {{ getSomething }}
      </div>
    </template>
    
    <script>
    import { mapActions, mapGetters, mapMutations } from "vuex";
    
    export default {
      name: "App",
      computed: {
        ...mapGetters(["getSomething"]), //<--- get a state from store
      },
      methods: {
        ...mapActions(["doSomethingAction"]), // <--- use dispatch froms store
        ...mapMutations(["updateSomething"]), // <-- use mutation from store
        async doSomethingInsideComponent() {
          // <-- component trigger for the promise forward
          await this.doSomethingAction().then(() => {
            // HERE YOU DO SOMETHING AFTER THE DISPTACH IS FULLFILLED...
            this.updateSomething();
          });
        },
      },
    };
    </script>
    
    <style>
    #app {
      font-family: "Avenir", Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    

    i hope my comments explain enough. if not please tell me. Here is a working example CodeSandbox


    Update

        async setTrigger({ state }) { //<-------- set this function to "async"
         return await axios //<------------ return your axios call here, and await 
            .post(
              "https://xxx.us/api/savetriggers",
              {
                organizationsDefaultTriggerTime: state.organizationsDefaultTriggerTime,
                runFailedDefaultTriggerTime: state.runFailedDefaultTriggerTime,
              },
              {
                headers: {
                  Authorization: `Bearer ${state.currentAuthToken}`,
                },
              }
            )
            .then((response) => {
              console.log(response.data);
              return response //<--------- return the response here
            })
            .catch((error) => {
              console.log(error.data);
            });
        },
    
    

    inside your component you are then able to handle the response with a then chaining

    do this to achieve this:

    this.$store.dispatch("setTrigger").then((response) => {
      // do what you want here because the store dispatch is forwarded to here
      console.log(response)
    });
    

    Sidenote

    you really should learn more about Promises - Javascript