MEAG
MEAG

Reputation: 127

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?

Upvotes: 1

Views: 984

Answers (1)

Deniz
Deniz

Reputation: 1503

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

Upvotes: 2

Related Questions