axios を使った action を呼び出し元で同期的に扱いたい
Vuex の action で axios を用いて API を実行する処理を利用する際に詰まったため記録
目的
store 外で actions を用いる際に、action の実行結果を待機したうえで別の処理を実行したい。
コード
// items.js
const state = {
items: []
}
const getters = {
getItems: state => state.items
}
const actions = {
fetchItems({ commit, state }) {
axios.get(`/api/items`)
.then(response => {
commit('receiveItems', response.data);
})
}
}
const mutations = {
receiveItems (state, items) {
state.items = items;
}
}
// item.vue
...
mounted () {
this.showItems()
}
methods: {
showItems () {
items = this.$store.getters('items/getItems')
this.$store.dispatch('items/fetchItems')
.then(() => {
console.log(items)
})
}
}
- console 上に item の一覧が配列となって表示されていることを期待するが、結果は空。
解決方法
// items.js
...
const actions = {
fetchItems({ commit, state }) {
return axios.get(`/api/items`)
.then(response => {
commit('receiveItems', response.data);
})
}
}
原因
基本中の基本だが、JavaScript の場合、関数の返り値を呼び出し元で扱いたい場合はでは return
で返さないといけない。
問題のコードでもアクション自体は実行できるが、Promise オブジェクトが返り値として返らないため呼び出し元では .then()
をチェーンできない。