ng-show element is visible even though the expression evaluates to false

2.8k Views Asked by At

This one has got me stumped. It was working last week and suddenly stopped working. An element I have ng-show on is visible even though it's evaluating as false.

In the script:

$scope.alerts = { message: '', success: false, error: false, notice: false };

In the markup:

<div class="alert success" ng-show="alerts.success">
    <strong>SUCCESS!</strong>
    <div>{{alerts.message}}</div>
</div>

For testing purposes, I placed a {{alerts.success}} in the markup to make sure it is indeed evaluating to false, and i can confirm that it is.

Any idea why this would happen?

ps: Unfortunately, I can't post more code than this.

3

There are 3 best solutions below

0
On BEST ANSWER

Apparently, this is a known problem (https://github.com/angular/angular.js/issues/4394) with version 1.2. We introduced ng-csp into our project last week and it doesn't play well with ng-show/hide. I added the css snippet below which I got from https://groups.google.com/forum/#!topic/angular/w00KgEi1DLk and it works fine now. Thanks for your responses!

@charset "UTF-8";

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
.ng-cloak, .x-ng-cloak,
.ng-hide {
  display: none !important;
}

ng\:form {
  display: block;
}
1
On

Something else must be happening in your code. ng-show is capable of checking object properties.

Here is a working plunker. http://plnkr.co/edit/QliAbg7zfkWgTVUTuLVp?p=preview

2
On

You must have written $scope.alerts.success = false; inside a callback function. Yes, the value of $scope.alerts.success will become false, as it will properly show in {{alerts.success}} in your markup.

To combat this, you'll need to wrap $scope.$apply around the variable assignment statement:

SomeService.DoSomething(function success() { /* Success Code */}, 
     function error() {
          $scope.$apply(function() {
              $scope.alerts.success = false;
          });
     })
);

Angular isn't exactly fully automatic with data bainding. Yes, it did update the value in the variable, but it didn't automatically update the UI. When you change a value inside a callback (including setTimeout), you must wrap your value-assigning code with $scope.$apply so that Angular will update the UI.