Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngProgress loading bar on every page load

Tags:

angularjs

I am using AngularJS and ngProgress to display a YouTube-like loading bar at the top of my site.

The bar is started, then new data is loaded in via ajax, and once the request is finished, the bar is completed.

Example:

var TestCtrl = function( $scope, $location, Tests, ngProgress ) 
{
    // start progressbar
    ngProgress.start();

    $scope.tests = Tests.query(
        function()
        {
            // end progressbar
            ngProgress.complete()
        }
    );
};  

Now my question is: How can I integrate this principle higher up in the order of things, such that I don't have to repeat the code for every single controller?

like image 774
Ben Avatar asked Apr 27 '26 04:04

Ben


1 Answers

You could use a service which controls ngProgress (acting like a wrapper over it) and listen for changes in the url.

  • Each time the url changes the event $locationChangeSuccess is broadcasted (more info at $location) which we could listen to invoke ngProgress.start()
  • However we don't know when it's completed (we can't have a bar on the top loading forever), therefore we need to call ngProgress.complete() explicitly in our controllers OR we could assume that our async functions might take like 5 seconds to be completed and call ngProgress.complete() using a timer in our wrapper service
  • When the loading bar is already visible and there's a change in the url we need to reset the status of the bar by calling ngProgress.reset()

You can use the following approach to solve these problems:

angular.module('myApp').factory('Progress', function (ngProgress) {
    var timer;
    return {
        start: function () {
            var me = this;
            // reset the status of the progress bar
            me.reset();
            // if the `complete` method is not called
            // complete the progress of the bar after 5 seconds
            timer = setTimeout(function () {
                me.complete();
            }, 5000);
        },
        complete: function () {
            ngProgress.complete();
            if (timer) {
                // remove the 5 second timer
                clearTimeout(timer);
                timer = null;
            }
        },
        reset: function () {             
            if (timer) {
                // remove the 5 second timer
                clearTimeout(timer);
                // reset the progress bar
                ngProgress.reset();
            }
            // start the progress bar
            ngProgress.start();
        }
    };
});

To listen for changes in the url and show the progress bar we could use:

angular.module('myApp')
    .run(function (Progress) {
        $rootScope.$on('$locationChangeSuccess', function () {
            Progress.start();
        });
    }

Now we can manually control the completeness of the status bar by injecting the Progress service and calling the method Progress.complete() when all of our async functions have finished (we could also control this from any service that makes async calls):

angular.module('myApp')
    .controller('SomeCtrl', function (Progress) {
        setTimeout(function () {
            Progress.complete();
        }, 2000);
    });
like image 145
Mauricio Poppe Avatar answered Apr 28 '26 18:04

Mauricio Poppe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!