Vue – How to show a progress bar during data fetching operations

Advertisements

I want to create a progress bar using vue js and bootstrap for my desktop app.
I have this code into the template that will render the needed markup

    <div class="container-fluid p-0 vh-100" v-if="isLoading">
        <div class="row m-0">
            <div class="col-4 mx-auto">
                <div class="progress rounded-0" role="progressbar">
                    <div class="progress-bar text-uppercase" id="progressBar" style="width: 0%;"></div>
                </div>
            </div>
        </div>
    </div>

Into a dedicated method I’ve the following code, I need to implement also some logics that are responsable to load data and update a supabase database. My idea is to hide the progress bar when all the data are loaded

        updateDatabase() {
            const preloader = document.getElementById('progressBar')
            setTimeout( () => { 
                preloader.style.width = '15%'
                preloader.style.width = '30%'
                preloader.style.width = '45%'
                preloader.style.width = '60%'
                preloader.style.width = '75%'
                preloader.style.width = '90%'
                preloader.style.width = '100%'
            }, 1500)
            //other db logics
        }

I also have a data property named isLoading that is set to true when the progress bar and the database loading/update process is in progress. I’ve noticed that the progress bar will disappear immediately and this isn’t what I was expecting. How I can correctly set a timeout and modify the progress bar to reflect the width percentage changing? If I set at the end of the set timeout the isLoading variable, it will be immediately set to false and as I’ve explained the progress bar disappear. Thank you for the help.

>Solution :

Within the example given the setTimeout will wait for 1500ms and then run all the code inside of it, this will result in the width being set immediately from 15 to 30 to 45 to etc… if you want to display progress you will have to use an interval which increases the width by an amount till it reaches 100% and then removing the isLoading. A way to do this is by using setInterval like this

this.interval = setInterval(() => {
  if(this.width === 100) {
    this.width = 0;
    clearInterval(this.interval);
    this.isLoading = false;
  }
  const newWidth = this.width + Math.floor(Math.random() * 15);
  this.width = this.newWidth <= 100 ? newWidth : 100;

  preloader.style.width = this.width + '%';
}, 150);

and then creating interval and width within your data. Of course this is a simple example of how to do it but I hope this examplifies what I mean with my answer, good luck!

P.S. I have also added a random value in the example to generate a value between 0 and 15 to make it seem more natural 😉

P.S. P.S. within Vue the preferred way to select an element is by using the $refs so setting the ref attribute on the element with for example ref="progress-bar" and then selecting it in your code with this.$refs['progress-bar'];

Leave a ReplyCancel reply