1

I'm attempting to use ng-show to display a loading bar while any async calls are done in the background. Simplified code example below but I find that both divs are displayed and the loading div is not hidden after $scope.page_loaded becomes true.

I'm fairly new to Angular so this may be a rookie error.

EDIT: Even in the simplistic example below, without any async calls, I get both divs displayed.

controllers.js

controllers.controller('AuthController', ['$scope', '$window', function($scope, $window) {
    $scope.page_loaded = false;

// DO SOME LOGIC HERE

    $scope.page_loaded = true;

}]);

index.html

<div class="page-content" layout="row" flex layout-align="center center" ng-show="!page_loaded">
    <div class="loading">
        <p class="loading-text">Loading...</p>
        <md-progress-linear md-mode="indeterminate"></md-progress-linear>
    </div>
</div>

<div ng-view class="page-content" layout="row" flex ng-show="page_loaded"></div>
christophmccann
  • 4,181
  • 7
  • 42
  • 66

4 Answers4

1

You can try wrapping it in a timeout:

// DO SOME LOGIC HERE

$timeout(function () {
    $scope.page_loaded = true;
)},0);

Don't forget to inject the module: controllers.controller('AuthController', ['$scope', '$window', '$timeout', function($scope, $window, $timeout) {

I personally don't like using timeouts, but if the DOM isn't updating, this can be a workaround.

The assumption here is that your //DO SOME LOGIC HERE is influencing the change in your $scope.page_loaded. The timeout forces an event into the stack allowing the browser to catch up, this is why it is set to 0. We're not using the $timeout(fn,0); as a means to time a change after a period of time.

Fred
  • 1,297
  • 2
  • 11
  • 18
  • More on that: http://stackoverflow.com/questions/22881374/why-is-this-simple-angularjs-ng-show-not-working – isherwood Aug 26 '15 at 17:11
0

updated

<div class="page-content" layout="row" flex layout-align="center      center" ng-show="page_loaded">
<div class="loading">
    <p class="loading-text">Loading...</p>
    <md-progress-linear md-mode="indeterminate"></md-progress-linear>
</div>

<div ng-view class="page-content" layout="row" flex ng-show="!page_loaded"></div>


controllers.controller('AuthController', ['$scope', '$window', function($scope, $window) {
  $scope.page_loaded = true;
      // DO SOME LOGIC HERE
  if(SOMETHING_RETURNS_TRUE) {
    $scope.page_loaded = false;
    ///THIS WILL HIDE THE LOADER
  }
}]);

The mistake you are making is that, you're setting it to false and then it evaluates to true on load, so it will definitely show.

However you can then use a $timeout, to set an interval just like using setTimeout in pure JS, so after a time it changes it back to show last div.

$timeout(function(){
    $scope.page_loaded = false;
}, 5000);

Don't forget to inject $timeout.

0

I think you need actual logic to instantiate the change from false to true.. To expand on Fred's answer: here is a plunker

http://plnkr.co/edit/NqZ5YdHzVcoGnceEU3sV?p=preview

$scope.pageloaded = false;

$timeout(function () {
    $scope.pageloaded = true;
}, 2000);

<div ng-show="!pageloaded">
  Loading... 
</div>

<div ng-show="pageloaded">
  page_loaded 
</div>
jakeforaker
  • 1,622
  • 1
  • 20
  • 34
0

I was able to fix this by using $rootScope instead. That being said, I have no idea why that works and $scope doesn't.

christophmccann
  • 4,181
  • 7
  • 42
  • 66