Always remember the return statement when dealing with asyncronous tasks.
You have two options to refactorize your code, keeping promise or async/await.
Option 1: async/await
async loadConstituencyByAreaCodeAndParliament({ commit }, { parliament_id, area_code }) {
try {
const { data } = await axios('/cc-api/area-code/' + parliament_id + '/' + area_code)
commit('SET_CONSTITUENCY', data)
return data
} catch (error) {
commit('SET_CONSTITUENCY', null)
return error
}
}
Notes:
return statement in both blocks of try/catch.
.get in axios is optional, since default is get method.
- You can use object Destructuring assignment with
{ data } by default with axios. If I'm not wrong the default good http responses retrieve data.
Even a more sophisticated way could be const { data: constituencyResponse } = await... then you work with constituencyResponse and you probably save 2 or 3 lines of code each time.
Option 2: Promise
First Path: Make everything in the store.
// actions
loadConstituencyByAreaCodeAndParliament({ commit, dispatch }, { parliament_id, area_code }) {
axios('/cc-api/area-code/' + parliament_id + '/' + area_code)
.then(({data}) => {
commit('SET_CONSTITUENCY', data)
dispatch('actionTwo', constituency)
})
.catch((error) => {
console.log("error", error)
commit('SET_CONSTITUENCY', null)
})
}
actionTwo({commit}, constituency) {
console.log("actionTwo", constituency)
// do something
commit('COMMIT', 'Final value')
}
// Component
// You handle it with a computed property either referencing a getter or the store state.
{
computed: {
getConstituency(){
return this.$store.state.constituency
},
getSomeOtherConstituency(){
return this.$store.state.constituency.something / 3
}
},
// Optionally if you want to listen and react to changes use a `watcher`.
watch: {
// Gets excecuted each time getConstituency updates.
// ! Must have the same name.
getConstituency(update) {
// Do something, `update` is the new value.
}
}
}
Second Path: Handle data inside the component, then update the store.
Vue component.
methods: {
search_area_code(submitEvent) {
const parliament_id = this.parliament_id
const area_code = submitEvent.target.elements.area_code.value
axios('/cc-api/area-code/' + parliament_id + '/' + area_code)
.then(({data: constituency}) => {
this.$store.commit('SET_CONSTITUENCY', constituency)
// Do whatever you want with constituency now inside the component.
})
.catch((error) => {
console.log("error", error)
this.$store.commit('SET_CONSTITUENCY', null)
})
}
},
Notes:
$store.dispatch method returns a promise but still the constituency variable receives not the data fetched with the loadConstituencyByAreaCodeAndParliament action but remains empty.
When I enter the area code a second time everything works well.
I think the problem here is that you either handled bad the asyncronous code or trying to implement a custom pattern to work around.
As I said earlier put store getters in computed properties,
Look at this example in the Vuex-docs.
Code insights:
// Your action doesn't return anything, you must `return axios.get` inside it.
this.$store.dispatch('loadConstituencyByAreaCodeAndParliament', payload).then(() => {
let constituency = this.$store.getters.getConstituency()
})
// without the `return` statement the code above can be translated to
this.$store.dispatch('loadConstituencyByAreaCodeAndParliament', payload)
let constituency = this.$store.getters.getConstituency()
// If you opt for async a valid way would be
async doSomething(){
await this.$store.dispatch('loadConstituencyByAreaCodeAndParliament', payload)
let constituency = this.$store.getters.getConstituency()
}
// IF it still doesnt update anything try `$nextTick` https://vuejs.org/v2/api/
this.$nextTick(() => {
this.data = this.$store.getters.getConstituency()
})
I hope some of this has been helpful.
returntheaxios.getcall (right now, it's just a "fire & forget" promise)mapGettersrather than imperatively settingconstituency.