Tengo una aplicación Vuejs/Nuxtjs dentro de la cual necesito acceder al state de una tienda Vuex después de que haya sido modificada por Vuex action . Actualmente, cuando intento ejecutar la action y la assignment , obtengo el estado anterior y no el que se actualizó después de action .
¿Cómo hacer que el código espere a que se complete la action y luego ejecute la siguiente declaración? El siguiente es el código que tengo actualmente: Componente Vuejs:
<template> <div> <input v-model="formData.value" type="text"> <button @click="performAction"> Click Me </button> </div> </template> <script> export default { data () { return { formData: { value: '', returnValue: '' } } }, methods: { performAction () { // Set the value within the Vuex Store this.$store.commit('modules/DataStore/populateData', this.formData.value) // Perform the Action this.$store.dispatch('modules/DataStore/getData').then(() => { console.log("AFTER COMPLETE ACTION") }) // Assign the update value to the variable this.formData.returnValue = this.$store.state.modules.DataStore.data } } } </script> <style> </style>Tienda Vuex:
export const state = () => ({ data:'' }) export const mutations = { populateData (state, data) { state.data = data } } export const actions = { getData ({ commit, state, dispatch }) { const headers = { 'Content-Type': 'application/json' } this.$axios .post('/getUrlData', state.data, { headers }) .then((response) => { console.log("WITHIN RESPONSE") commit('populateData',response.data) }) .catch((error) => { commit('populateData', 'Unable to obtain data, Error : ' + error) }) } }Lo siguiente es lo que probé y nada funciona en este momento:
.then() .Async y await , pero ambos no funcionan.Cualquier sugerencia será realmente apreciada. Gracias por adelantado.
Puedes crear getter en vuex :
export const getters = { getData: (state) => state.data, }; export const actions = { async setData ({ commit }, data) { const headers = { 'Content-Type': 'application/json' } await this.$axios .post('/getUrlData', data, { headers }) .then((response) => { console.log("WITHIN RESPONSE") commit('populateData',response.data) }) .catch((error) => { commit('populateData', 'Unable to obtain data, Error : ' + error) }) } }luego, en el componente, puede asignar captadores y acciones, y llamarlos:
import { mapGetters, mapActions } from 'vuex' computed: { ...mapGetters(['getData']), }, methods: { ...mapActions(['performAction']), async performAction() { await this.setData(this.formData.value) this.formData.returnValue = this.getData } }Debe devolver su promesa en su si desea encadenarla en el método de llamada. p.ej:
getData ({ commit, state, dispatch }) { const headers = { 'Content-Type': 'application/json' } return this.$axios // now this promise will be returned and you can chain your methods together .post('/getUrlData', state.data, { headers }) .then((response) => { console.log("WITHIN RESPONSE") commit('populateData',response.data); return response.data; //this will allow you do send the data through to the next Then() call if you want to }) .catch((error) => { commit('populateData', 'Unable to obtain data, Error : ' + error) }) }Esta situación es mucho más fácil de manejar con async-await IMO. Se vuelve:
export const actions = { async getData ({ commit, state, dispatch }) { const headers = { 'Content-Type': 'application/json' } const response = await this.$axios.post('/getUrlData', state.data, { headers }); console.log("WITHIN RESPONSE") commit('populateData',response.data); } }y
methods: { async performAction () { // Set the value within the Vuex Store this.$store.commit('modules/DataStore/populateData', this.formData.value) // Perform the Action await this.$store.dispatch('modules/DataStore/getData'); console.log("AFTER COMPLETE ACTION"); // Assign the update value to the variable this.formData.returnValue = this.$store.state.modules.DataStore.data } }