Skip to content

Suggestion for website FAQ: Working Code Example for Loading Bar using a Worker #385

@robcbryant

Description

@robcbryant

I struggled getting this to work--but finally came up with a solution. I noticed some others struggling with the same, so I figured I clean my code I used up and put it here to offer you for the website FAQ:

To create a percent complete loading bar for PapaParse, you will need to use a worker. Create a worker file that contains:

worker.js

//****Here you should cut and paste the the PapaParse.min.js file or include it with js. I chose to just cut and paste it.
onmessage = function(file) {
        var size = file.data.size;
        var percent = 0;
        Papa.parse(file.data, {
            worker: true,
            header: true,
            step: function(results, parser) {
                var progress = results.meta.cursor;
                percent = Math.round(progress / size * 100);
                //this posts the percentage to to the corresponding worker function in the main .js file
                 postMessage(percent);
            },
            complete: function(results){
                //I send a '-1' to signal the main.js worker listener the parsing is complete
                postMessage(-1);
            }         
    });
}

After you save that .js file somewhere, then write the main .js file that will be included in the webpage:

main.js

//Note: I am using jQuery / Bootstrap--you can optionally use other methods or plain jscript to accomplish this.
    //This is my progress bar div I'm changing
    $progressBar = $('#file-read-progress-bar');
     //Make sure you include the worker file you made here at the top of the main .js file
     var myWorker = new Worker('http://www.yoursite.com/your-worker-file-above.js');
   
        //This function is called by the worker.js file you made and is what asynchronously updates the progress bar
        myWorker.onmessage = function (message) {
            //I use a -1 to signal the completion of the PapaParse step function
            if (message.data == -1){
                //update progress bar to completed(Note: These are Bootstrap specific changes-- it may differ for you
                $progressBar.removeClass('active progress-bar-striped');
                $progressBar.addClass('progress-bar-success');
                $progressBar.html = 'Successful Load!'; 
            //If we aren't done loading, update the progress bar here
            } else {
               //This changes the width of the Bootstrap progress bar according to the provided percentage
                $progressBar.css('width', e.data[0]+'%');
            }
    }
    
   //This function activates when an <input type='file'> element is modified/used on the page
    function readCSVFileListener(fileInputEvent) {
        //Reset the progress bar: This ensures if the user selects another file, it resets the bar back to zero
        $progressBar.addClass('active progress-bar-striped');
        $progressBar.removeClass('progress-bar-success');
        $progressBar.css('width', '0%');
         myWorker.postMessage(fileInputEvent.target.files[0]);//This is a single file input--so we only expect the first file in the array
    }
    
    //Set the listener up
    document.getElementById('csv').addEventListener('change', readCSVFileListener, false);

Create both these files, import the main.js script on the webpage, and add the worker.js to the new Worker(url-to-worker) line in the main.js code.

Assuming your element ids are setup properly, and your css is setup properly--this should work. I will say it is much slower than normal--but I prefer the user-end experience to be more informed and wait longer than have no feedback on what they're doing.

Let me know what you think!

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions