9

When using AngularJS and doing a redirect using $location.path('/path') the new page takes a while to load, especially on mobile.

Is there a way to add a progress bar for loading? Maybe something like YouTube has?

5 Answers 5

21

For a progress bar as YouTube has, you can take a look at ngprogress. Then just after the configuration of your app (for example), you can intercept route's events.

And do something like:

app.run(function($rootScope, ngProgress) {
  $rootScope.$on('$routeChangeStart', function() {
    ngProgress.start();
  });

  $rootScope.$on('$routeChangeSuccess', function() {
    ngProgress.complete();
  });
  // Do the same with $routeChangeError
});
Sign up to request clarification or add additional context in comments.

2 Comments

You forgot to inject ngProgress: .run(function($rootScope, ngProgress)
N.b. this answer no longer applies. Look at @rsobon 's answer at the bottom of this page for an up to date implementation.
5

Since @Luc's anwser ngProgress changed a bit, and now you can only inject ngProgressFactory, that has to be used to create ngProgress instance. Also contrary to @Ketan Patil's answer you should only instantiate ngProgress once:

angular.module('appRoutes', ['ngProgress']).run(function ($rootScope, ngProgressFactory) { 

    // first create instance when app starts
    $rootScope.progressbar = ngProgressFactory.createInstance();

    $rootScope.$on("$routeChangeStart", function () {
        $rootScope.progressbar.start();
    });

    $rootScope.$on("$routeChangeSuccess", function () {
        $rootScope.progressbar.complete();
    });
});

Comments

1

if it is the next route that takes time to load e.g. making ajax call before the controller is run (resolve config on route) then make use of $route service's $routeChangeStart, $routeChangeSuccess and $routeChangeError events.

register a top level controller (outside ng-view) that listens to these events and manages a boolean variable in its $scope.

use this variable with ng-show to overlay a "loading, please wait" div.

if the next route loads fast (i.e. its controller runs quickly) but data that are requested by the controller take a long to load then, i'm afraid, you have to manage the visibility state of spinners in your controller and view.

something like:

$scope.data = null;
$http.get("/whatever").success(function(data) {
    $scope.data = data;
});

<div ng-show="data !== null">...</div>
<div ng-show="data === null" class="spinner"></div>

Comments

1

use angular-loading-bar

Standalone demo here .. https://github.com/danday74/angular-loading-bar-standalone-demo

Comments

-1

Here is a working solution which I am using in my application. ngProgress is the best library out there for showing load-bars when changing urls.

Remember to inject the ngProgressFactory instead of ngProgress, as opposed to Luc's solution.

angular.module('appRoutes', []).run(function ($rootScope, ngProgressFactory) {
    $rootScope.$on("$routeChangeStart", function () {
        $rootScope.progressbar = ngProgressFactory.createInstance();
        $rootScope.progressbar.start();

    });

    $rootScope.$on("$routeChangeSuccess", function () {
        $rootScope.progressbar.complete();
    });
});

Update Nov-2015 - After analyzing this approach with chrome timings, I have observed that this would not be the correct way for adding a loading bar. Sure, the loading bar will be visible to visitors,but it will not be in sync with actual page load timings.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.