Displaying a progress bar while fetching data in Vue: A step-by-step guide

I am working on developing a progress bar using vue js and bootstrap for my desktop application. Within the template, I have the code that will generate the necessary 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>

In a specific method, I have the following code, in which I need to incorporate some logic to load data and update a Supabase database. My goal is to hide the progress bar once all the data has been 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
        }

Additionally, I have a data property called isLoading that is initially set to true when the progress bar and database loading/update process are ongoing. However, I noticed that the progress bar disappears immediately, which was not the intended behavior. How can I properly implement a timeout function to gradually adjust the width percentage of the progress bar? Setting the isLoading variable at the end of the timeout causes it to be set to false immediately, resulting in the disappearance of the progress bar. Any guidance on this issue would be greatly appreciated. Thank you.

Answer №1

In the given example, the setTimeout function will wait for 1500ms before executing the code inside it. This will result in the width changing from 15 to 30 to 45, and so on. If you want to display progress continuously, you should use an interval that increases the width incrementally until it reaches 100% and then removes the isLoading flag. You can achieve this by utilizing setInterval as shown below:

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);

Make sure to define interval and width within your data object. This is a simplistic demonstration, but I hope it illustrates my point. Good luck!

P.S. To add a touch of randomness, a random value between 0 and 15 has been included in the example to create a more natural effect ;)

P.S. P.S. In Vue, it is recommended to select elements using $refs. Set the ref attribute on the element (e.g., ref="progress-bar") and access it in your code using this.$refs['progress-bar'];

Answer №2

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)

When assigning multiple values to an attribute at the same time, only the last assignment will take effect. Therefore, in this case, only preloader.style.width = '100%' will be executed.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unexpected color changes when hovering over sparkline graphs

One of the jquery plugins I'm using is called sparkline Here's an example of how I am using it: $(function(){ $("#sparkline5").sparkline([2, 8, 10, 22], { type: 'pie', height: '140', sliceColors: [ ...

Guide to efficiently utilizing flex to horizontally position two elements next to each other in a Material UI and ReactJS environment

I have successfully achieved side-by-side components of two cards from Material-UI. However, I am facing an issue when expanding one of the cards. The problem is that Card 1 automatically expands to match the size of Card 2 when Card 2 is expanded, even th ...

HTML/PHP/JS - Submit Form and Upload File Simultaneously

I need to create a form with a Photo Upload Input that allows users to upload pictures before submitting the form for faster processing. The form should also support uploading multiple files, display a progress bar, and provide a preview of the uploaded im ...

Update the navigation bar from displaying "LOGIN" to "LOGOUT

I am facing a challenge in updating the navbar login link to a logout link once the user logs in. I have attempted the following: header.ejs: <ul class="nav navbar-nav navbar-right"> <li id="home"><a href="/ ...

Executing a request via ajax using a radio button

Here is the input that I am working with: <input id="offline-42" onclick="javascript:checkoutSwitch(false);controlDivPayment('42');" name="payment" type="radio" value="offline-42" /> I am attempting to use ajax to add a product to the sh ...

Is it possible for users to change months on a website using the Python calendar library?

Currently, I am in the process of developing a web application using Django. To create an HTML calendar, I am utilizing the Python calendar library. I am curious to know if there is a built-in method to enable users to switch between months while navigat ...

Is there a way for me to customize the appearance of the Material UI switch component when it is in the checked

I am seeking to customize the color of the switch component based on its checked and unchecked state. By default, it displays in red. My goal is to have the "ball knob" appear yellow when the switch is checked and grey when it is not. This styling must be ...

What causes the watch method in Vue.js to be activated even when the prop has not been altered?

One thing to note is that the watch method for a property or data is triggered when it is changed or reassigned. In the following code snippet, the watch method for initTasks appears to be triggered even though initTasks itself is not modified. The purpo ...

Several levels piled one on top of the other

I'm in the process of designing a section for a webpage using Bootstrap 3.0, and I want to layer three divs or sections on top of each other. The stacking order should be as follows: background "squares," footer, and foreground "squares" with images. ...

The equation of jquery plus ie7 results in an undefined value

I am experiencing a strange issue in IE7 with a jQuery script. This problem seems to only occur in IE7. In summary, when I check the console window, it shows that jQuery is not defined - even though I have loaded jQuery (version 1.7.1) from my disk and can ...

Streamline jQuery code for dynamically populating two select dropdowns

I am looking to streamline and enhance this script to make it more dynamic. There could be multiple items in options, potentially even up to ten items. In the current scenario, the maximum number of items allowed is 2. The total value selected across both ...

Exploring Vue: A Guide to Utilizing Directives Provided by Libraries

I am attempting to utilize the library found here: https://github.com/rigor789/vue-scrollto However, I am encountering difficulties with utilizing it and the provided instructions are not very clear. The instructions state that I should do the following: ...

What is the best way to divide files in a Vue.js-based spa into both public and private sections?

Looking to divide my Vue.js and Ionic SPA app into a public section (featuring just login, password request, and minimal content) and the remaining functionality... I've come across the possibility of implementing a Multi-Page Application utilizing w ...

problem with the clientHeight attribute in window event handlers

The component below is designed to react to changes in window resize based on the container height. However, there seems to be an issue where the containerHeight variable increases as the window size decreases, but does not decrease when I make the window ...

Step-by-step guide on integrating a custom JS file into an Angular component

Trying to grasp Angular, I embarked on adding some JavaScript logic to one of my components from a separate JS file. While following advice from a similar query (How to add custom js file to angular component like css file), it seems I missed something cru ...

How to retrieve the input value in React Autosuggest

I recently began my journey into learning JavaScript and React. Currently, I am working on creating a simple table with material design. The goal is to be able to add rows to the table through a form popup and delete rows using an icon within each row. On ...

Incorporate action icons (such as edit and delete) into a table in React.js using material-ui

Within my existing table, I utilized a library known as react-bootstrap-table-next This library effectively displays data in a table format with values originating from a JSON response Now, my goal is to integrate an Action column that includes options f ...

Using HTML and JavaScript, we can set two different color values - one for the background and one for the h1 title

I am trying to save two values, one for the h1 tag and one for the body background. I want the user to select color 1 and color 2. When I press the third button, all changes should be applied and the colors should change. I have attempted this but with no ...

Creating a single-level menu with Bootstrap using nested angular ng-repeat

I am currently working on developing a single level menu using bootstrap and angularJS. The menu is successfully functioning with JavaScript and HTML when the <li> element is dynamically created. Now, I am attempting to integrate AngularJS into the ...

Is there a way to stop vue-panZoom from functioning temporarily?

I am working with a Grid that includes the use of vue-panZoom. Within the Grid, there is a section that utilizes vue-draggable-resizable, similar to what is depicted in the image below: Image When I drag the gray square (vue-draggable-resizable), the bl ...