Search code examples
apivue.jsaxiosvuex

blink store data after change route


how can i avoid the data blink after update store data? you can see the effect here:

https://drive.google.com/file/d/178raL6AJiC4bpIOImnaTKh6Yf9GruTCz/view?usp=sharing

component:

[...]
    mounted() {
        this.getIdeasFromBoard(this.$route.params.board_id);
    },
[...]

store:

[...]
const actions = {
    getIdeasFromBoard({ commit, dispatch }, board_id) {
        apiClient
            .get('/ideas/' + board_id)
            .then((result) => {
                console.log('success');
                commit("SET_IDEAS_BOARD", result.data);
            })
            .catch(error => {
                console.log('error' + error);
                alert("You have failed to log in. Try again with another credentials.");
                dispatch('auth/logout', null,  { root: true });
                this.$router.push({ name: "public" });
            });
    },
[...]

i've searched some simple tutorial about consuming api with error handling, but didnt find it.

thanks


Solution

  • It's because IDEAS_BOARD has the previous data until the new API call is completed. You would need to display a loader or a blank screen until the API call for the selected board is completed.

    From actions, return a promise so that your component knows when is the call completed.

    getIdeasFromBoard({ commit, dispatch }, board_id) {
      return new Promise((resolve, reject) => {
          apiClient
            .get('/ideas/' + board_id)
            .then((result) => {
                console.log('success');
                commit("SET_IDEAS_BOARD", result.data);
                resolve()
            })
            .catch(error => {
                console.log('error' + error);
                alert("You have failed to log in. Try again with another credentials.");
                dispatch('auth/logout', null,  { root: true });
                this.$router.push({ name: "public" });
                reject()
            });
      })
    },
    

    In your .vue component,

    async mounted () {
      this.loading = true // some flag to display a loader instead of data
      await this.$store.dispatch()
      this.loading = false
    }
    

    There must be some other ways too like having this loading flag in the Vuex store. But it depends on you