LoginSignup
15
10

More than 3 years have passed since last update.

【vue/vuex】 Vuexでエラーハンドリングして、vueコンポーネントで評価する

Posted at

はじめに

VueコンポーネントからVuexのstore内部にAPI非同期通信するためにごにょごにょやっていました。
そこで、store内部でエラーハンドリングしつつ、vueコンポーネントでその結果を受けてアラートを出したり、finally処理をしたいと思ったときに自分用のメモした内容です。
※雰囲気覚えておくためのモノなのでミスしている部分あるかもしれません。

ES2015とかES2017の知識ないと無理でした。
まさかの過去の自分の投稿に救われました。

内容

Vueコンポーネントで、Vuex内部のstoreを通して、axiosライブラリを用いてAPI通信します。
VueやVuexの共有内容も兼ねてなるべく丁寧にお伝えします。
実際の構成と異なり、単純化しています。
また、vue-cliを使用していないので、構成が異なる部分があります。
Nuxt.jsとかから入った人も困惑すると思いますが、基礎部分は同じです。

VueやVuexのおさらい

VueやVuex何て知ってるから早くしろという人は本題まで飛ばしてください。
ファイル構成や流れ、実際のファイルを見ていただくほうが理解できると思うので、記述します。

【ファイル構成】

- public
  - index.html
- src
  - components
   - App.vue
  - store
    - api.js
  - main.js

【流れ】

ざっくり以下の流れになります。

public(index.html) -> src(main.js) -> components(App.vue) -> store(api.js)

【ファイル内容】

ファイル内部を記述します。
細かな部分は端折っています。

public(index.html)
<!DOCTYPE html>
<html lang="ja">
    <head>
        <script src="../src/main.js"></script>
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>

「el」要素で「public(index.html)」の「app」に対してrenderする書き方もできます。

src(main.js)
import Vue from 'vue';
import store from './store';
import App from './components/App.vue';

new Vue({
  store,
  render: h => h(App)
}).$mount('#app'); 

components(App.vue)
<template>
    <div>
        <button @click="getApi"></button>
        <ul>
            <li v-for="list in getApiData">
                {{ list }}
            </li>
        </ul>
    </div>
</template>

<script>
import App from './components'
import { mapGetters } from 'vuex'

export default ({
    methods: {
        getApi(){
            this.$store.dispatch('getApiInfoAction', {
                url: 'hogehoge.com',
                params: 'test'
            })
        }
    },
    computed: {
        ...mapGetters({
            getApiData: "getApiInfo"
        })
    }
})
</script>
store(api.js)
import axios from 'axios'
import Vuex from 'vuex'

Vue.use(Vuex);

const state = {
    message: "",
}

const getters = {
    getApiInfo(state) {
        return state.message
    }
}

const mutations = {
    getApiInfo(state, payload) {
        state.message = payload.message
    }
}

const actions = {
    async getApiInfoAction(context, payload) {
        const payload_data = {
            message: "",
        }
        await axios.get(payload.url, { params: payload.params })
            .then(response => {
                payload_data.message = response.data
            }).catch(error => {
                payload_data.message = error
            }).finally(() => {
                context.commit('getApiInfo', payload_data)
            })
        })
    }
}

const store = new Vuex.Store({
    state,
    getters,
    mutations,
    actions
})

export default store

本題

APIで処理が失敗したときにもっとキレイにかけないかな、components(App.vue)側でうまくやりたい、またうまくエラーハンドリングしたいという時に役立ったのが、Promiseでした。
自分の過去記事に助けられました。

結論

components(App.vue)
methods: {
    getApi(){
        this.$store.dispatch('getApiInfoAction', {
            url: 'hogehoge.com',
            params: 'test'
        }).then(response => {
            alert("ok beforeCreate: ", response)
        }, error => {
            alert("no beforeCreate: ", error)
        }).finally(() => {
            alert("yeah")
        })
    }
}
store(api.js)
const actions = {
    async getApiInfoAction(context, payload) {
        const payload_data = {
            message: "",
        }
        await new Promise((resolve, reject) => {
            axios.get(payload.url, { params: payload.params })
            .then(response => {
                payload_data.message = response.data
                resolve(response)
            }).catch(error => {
                payload_data.message = error
                reject(error)
            }).finally(() => {
                context.commit('getApiInfo', payload_data)
            })
        })
    }
}

こうすることで、
APIに成功すれば「resolve」を返し
失敗すれば、「reject」を返してくれるようになり
vueコンポーネント側で良いようにできるようになった。

まとめ

Promiseもasync/await、めっちゃ便利。

15
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
10