Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async/Await with Vuex dispatch

Tags:

I am making a loader for some components in my app.

Here is my component:

        mounted() {             this.loading = true;              this.getProduct();         },         methods: {             async getProduct() {                 await this.$store.dispatch('product/getProducts', 'bestseller');                  console.log(123);                  this.loading = false;             }         }, 

Vuex action:

getProducts({commit}, type) {         axios.get(`/api/products/${type}`)             .then(res => {                 let products = res.data;                 commit('SET_PRODUCTS', {products, type})             }).catch(err => {             console.log(err);         })     }, 

The problem is in this line: await this.$store.dispatch('product/getProducts', 'bestseller');

I expect the code will stop at that line and wait for data is loaded from AJAX call and then set the loading is false;

But it isn't. The loading is still set false and the console.log run before my data is ready.

I already tried to move async/await into Vuex action and it worked. However, I didn't get the difference between them.

Below code is worked for me:

Component:

mounted() {             this.loading = true;              this.$store.dispatch('product/getProducts', 'bestseller').then((res) => {                 this.loading = false;             });         }, 

Vuex action:

async getProducts({commit}, type) {         let res = await axios.get(`/api/products/${type}`);          commit('SET_PRODUCTS', {products: res.data, type});     } 
like image 956
user3118789 Avatar asked Apr 16 '19 04:04

user3118789


People also ask

Does Vuex Dispatch return a Promise?

It's possible for a store. dispatch to trigger multiple action handlers in different modules. In such a case the returned value will be a Promise that resolves when all triggered handlers have been resolved.

How do I dispatch an action on Vuex?

You can call another Vuex action by passing the name of that action as a string as the first argument of dispatch : const store = new Vuex. Store({ actions: { walk(context) { context. dispatch("goForward"); }, goForward(context) { // }, }, });

Are Vuex actions async?

In Vuex, actions are functions that call mutations. Actions exist because mutations must be synchronous, whereas actions can be asynchronous. You can define actions by passing a POJO as the actions property to the Vuex store constructor as shown below.

What is difference between dispatch and commit in Vuex?

Dispatch triggers an action whereas commit triggers a mutation. $dispatch is always used from your methods in routes/components. It sends a message to Vuex store to perform some action. The action can be performed any time after the current tick so that it will not affect the frontend performance.


1 Answers

Change this:

getProducts({commit}, type) {     axios.get(`/api/products/${type}`)         .then(res => {             let products = res.data;             commit('SET_PRODUCTS', {products, type})         }).catch(err => {         console.log(err);     }) }, 

To this:

getProducts({commit}, type) {     return axios.get(`/api/products/${type}`)         .then(res => {             let products = res.data;             commit('SET_PRODUCTS', {products, type})         }).catch(err => {         console.log(err);     }) }, 

Should work.

axios.get returns a promise. You would need to return that promise in order to let await wait for it. Otherwise, you are implicitly returning undefined and await undefined would immediately resolve.

like image 94
jian Avatar answered Sep 20 '22 17:09

jian