Adding delay after vuex state changes

Viewed 829

I am trying to add some delay to transitioning out of an element when the value - v-if directive binds to - changes from true to false. I am using Vuex to maintain the state of isLoading so that it is used in other components.

So I have an API call that sets this.$store.state.isLoading to true while waiting for response, and false once response is received. But the problem is that API response is almost instant and the progress bar only flashes for a split second.

<template>
  <div>
    <b-progress v-if="isLoading" :max="max">
      <b-progress-bar :value="count"></b-progress-bar>
    </b-progress>
  </div>
</template>

<script>
module.exports = {
    data() {
        return {
            count: 0,
            max: 100
        }
    },
    computed: {
        isLoading () {
            return this.$store.state.isLoading;
        }
    }
}
</script>

Is this the right thinking by adding delay after the state is changed? If so, what is the proper way to do it?

1 Answers

You should add the delay right after your API call, assuming you have a mutation named updateIsLoading to update the isLoading state.

fetch(url)
  .then(res => res.json())
  .then(res => {
    // do something with your data
    setTimeout(() => this.$store.commit('updateIsLoading'), 1000)
  })
  .catch(...)

If you need to set the delay once and for all, one solution is to create an action, and then dispatch the action after you get response from the API call.

actions: {
  updateIsLoading({ commit }) {
    setTimeout(() => commit('updateIsLoading'), 1000)
  }
}

If you really want to do this in your component, you can setup a watcher and update a local isLoading variable after some delay:

export default {
    data() {
        return {
            count: 0,
            max: 100,
            isLoading: false
        }
    },
    computed: {
        loading () {
            return this.$store.state.isLoading;
        }
    },
    watch: {
      loading(newVal, oldVal) {
        setTimeout(() => this.isLoading = newVal, 1000)
      }
    }
}
Related