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}); }
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.
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) { // }, }, });
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With