hafer
hafer

Reputation: 137

Axios promise is not throwing error in vue method

As the title says, I have a problem catching an error in a Vue method getTodo.
Click on Set incorrect url and then on Get Todo, you can see there is an error in the store as expected, but in Vue when the getTodo promise's then is executed, there's no error. If you select Set correct url then it works fine. Console logs should look like this:

error on store  
error on vue

JavaScript and HTML below:

const store = new Vuex.Store({
    state: {
        todo: '',
        msg: '',
        url: 'https://jsonplaceholder.typicode.com/todos/test',
        correct: false
    },
    mutations: {
        setTodo(state, payload) {
            state.todo = payload;
        },
        setMsg(state, payload) {
            state.msg = payload;
        },
        setCorrect(state) {
            state.url = 'https://jsonplaceholder.typicode.com/todos/1';
            state.correct = true;
        },
        setIncorrect(state) {
            state.url = 'https://jsonplaceholder.typicode.com/todos/test';
            state.correct = false;
        }
    },
    actions: {
        getTodo({ state, commit }) {
            return axios.get(state.url)
                .then(response => {
                    console.log('success on store');
                    commit('setMsg', 'success on store');
                    commit('setTodo', response.data);
                })
                .catch(error => {
                    console.log('error on store');
                    commit('setMsg', 'error on store');
                });
        }
    }
})
new Vue({
    el: '#app',
    data: {
        message: ''
    },
    computed: {
        todo() {
            return store.state.todo;
        },
        msg() {
            return store.state.msg;
        },
        correctUrl() {
            return store.state.correct;
        }
    },
    methods: {
        getTodo() {
            store.dispatch('getTodo').then(() => {
                console.log('success on vue');
                this.message = 'success on vue'
            }).catch((e) => {
                console.log('error on vue');
                this.message = 'error on vue';
            });
        },
        setCorrect() {
            store.commit('setCorrect');
        },
        setIncorrect() {
            store.commit('setIncorrect');
        }
    }
})
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    <div id="app">
        <p>{{ message }}</p>
        <p>{{ todo }}</p>
        <p>Correct url: {{ correctUrl }}</p>
        <button @click="getTodo">Get Todo</button>
        <button @click="setCorrect">Set correct url</button>
        <button @click="setIncorrect">Set incorrect url</button>
    </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</body>

</html>

Upvotes: 1

Views: 1917

Answers (1)

Husam Elbashir
Husam Elbashir

Reputation: 7197

You need to re-throw the error after catching it in your getTodo action ..

actions: {
        getTodo({ state, commit }) {
            return axios.get(state.url)
                .then(response => {
                    console.log('success on store');
                    commit('setMsg', 'success on store');
                    commit('setTodo', response.data);
                })
                .catch(error => {
                    console.log('error on store');
                    commit('setMsg', 'error on store');
                    throw error;
                });
        }
}

const store = new Vuex.Store({
    state: {
        todo: '',
        msg: '',
        url: 'https://jsonplaceholder.typicode.com/todos/test',
        correct: false
    },
    mutations: {
        setTodo(state, payload) {
            state.todo = payload;
        },
        setMsg(state, payload) {
            state.msg = payload;
        },
        setCorrect(state) {
            state.url = 'https://jsonplaceholder.typicode.com/todos/1';
            state.correct = true;
        },
        setIncorrect(state) {
            state.url = 'https://jsonplaceholder.typicode.com/todos/test';
            state.correct = false;
        }
    },
    actions: {
        getTodo({ state, commit }) {
            return axios.get(state.url)
                .then(response => {
                    console.log('success on store');
                    commit('setMsg', 'success on store');
                    commit('setTodo', response.data);
                })
                .catch(error => {
                    console.log('error on store');
                    commit('setMsg', 'error on store');
                    throw error;
                });
        }
    }
})
new Vue({
    el: '#app',
    data: {
        message: ''
    },
    computed: {
        todo() {
            return store.state.todo;
        },
        msg() {
            return store.state.msg;
        },
        correctUrl() {
            return store.state.correct;
        }
    },
    methods: {
        getTodo() {
            store.dispatch('getTodo').then(() => {
                console.log('success on vue');
                this.message = 'success on vue'
            }).catch((e) => {
                console.log('error on vue');
                this.message = 'error on vue';
            });
        },
        setCorrect() {
            store.commit('setCorrect');
        },
        setIncorrect() {
            store.commit('setIncorrect');
        }
    }
})
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    <div id="app">
        <p>{{ message }}</p>
        <p>{{ todo }}</p>
        <p>Correct url: {{ correctUrl }}</p>
        <button @click="getTodo">Get Todo</button>
        <button @click="setCorrect">Set correct url</button>
        <button @click="setIncorrect">Set incorrect url</button>
    </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</body>

</html>

Upvotes: 1

Related Questions