193

I am trying to show / hide some HTML using the ng-show and ng-hide functions provided by AngularJS.

According to the documentation, the respective usage for these functions are as follows:

ngHide – {expression} - If the expression truthy then the element is shown or hidden respectively. ngShow – {expression} - If the expression is truthy then the element is shown or hidden respectively.

This works for the following usecase:

<p ng-hide="true">I'm hidden</p>
<p ng-show="true">I'm shown</p>

However, should we use a parameter from an object as the expression then the ng-hide and ng-show are given the correct true/false value but the values are not treated as a boolean so always return false:

Source

<p ng-hide="{{foo.bar}}">I could be shown, or I could be hidden</p>
<p ng-show="{{foo.bar}}">I could be shown, or I could be hidden</p>

Result

<p ng-hide="true">I should be hidden but I'm actually shown</p>
<p ng-show="true">I should be shown but I'm actually hidden</p>

This is either a bug or I am not doing this correctly.

I cannot find any relative information on referencing object parameters as expressions so I was hoping anyone with a better understanding of AngularJS might be able to help me out?

georgeawg
  • 46,994
  • 13
  • 63
  • 85
My Head Hurts
  • 36,367
  • 15
  • 69
  • 110

7 Answers7

375

The foo.bar reference should not contain the braces:

<p ng-hide="foo.bar">I could be shown, or I could be hidden</p>
<p ng-show="foo.bar">I could be shown, or I could be hidden</p>

Angular expressions need to be within the curly-brace bindings, where as Angular directives do not.

See also Understanding Angular Templates.

Scott
  • 13,201
  • 20
  • 86
  • 146
My Head Hurts
  • 36,367
  • 15
  • 69
  • 110
  • 76
    "Angular expressions need to be within the curly-brace bindings, where as Angular directives do not." That line right there. I wish I could upvote this twice. – MushinNoShin May 13 '13 at 20:48
  • 3
    If You want to check if the filed has a value use: `

    I could be shown, or I could be hidden

    `
    – czerasz Nov 06 '13 at 15:19
  • 1
    Thanks, this was not very intuitive (as you can tell from all the up-votes) – Sentient Mar 14 '14 at 00:51
  • Thanks , this what i was looking for. – Satish Singh Apr 17 '14 at 08:22
  • 1
    The documentation for ng-hide (https://docs.angularjs.org/api/ng/directive/ngHide) specifically calls the argument an expression, which means that it requires curly braces. What am I missing here? – Ed Norris Jul 30 '14 at 18:52
  • 1
    This answer is actually not correct. Curly braces indicate that expression should be executed and its result should be inserted into the DOM, while directive may or may not treat attribute value as an expression depending on its logic. Some directives (ngHref) even support curly brace bindings. – Vasaka Aug 25 '14 at 06:08
  • Hi @Vasaka - thank you for your comment. It is my understanding that directives include support for embedded expressions (_"support for curly brace bindings"_ - as you put it) and a developer does not need to pick between one or the other. It is good to use both as Angular will bind a listener to these expressions and then update them using the `$watch()` function. It is probable that I am missing your point, so maybe you can explain in more detail for me and I can ammend my answer if required. Thanks – My Head Hurts Aug 25 '14 at 08:58
31

You can't use {{}} when using angular directives for binding with ng-model but for binding non-angular attributes you would have to use {{}}..

Eg:

ng-show="my-model"
title = "{{my-model}}"
iConnor
  • 19,153
  • 13
  • 57
  • 91
SHIVANG SANGHI
  • 465
  • 1
  • 6
  • 10
18

Try wrapping expression with:

$scope.$apply(function() {
   $scope.foo.bar=true;
})
hrn
  • 205
  • 1
  • 2
  • 7
    the `foo.bar = true` should be `scope.foo.bar = true`, to change the value of `foo.bar` – Rajkamal Subramanian Feb 13 '13 at 04:18
  • 1
    I had a strange problem where sometimes it would be shown and sometimes it would not, wrapping my scope updates in $scope.$apply(function () { }); worked for me :) – nevernew Sep 20 '15 at 04:40
  • I'm new to angular and I'd really rather not do this every time I need to set a variable. Can someone explain why this is sometimes needed? – davis Nov 05 '15 at 02:06
  • A [helpful blog post](http://jimhoskins.com/2012/12/17/angularjs-and-apply.html) helped me answer this. Turns out any Ajax or custom listeners will have issues updating and require a `$scope.$apply` – davis Nov 05 '15 at 02:09
7

Since ng-show is an angular attribute i think, we don't need to put the evaluation flower brackets ({{}})..

For attributes like class we need to encapsulate the variables with evaluation flower brackets ({{}}).

Rajkamal Subramanian
  • 6,636
  • 4
  • 49
  • 63
  • close - I looked into it and it seems that angular [expressions](http://docs.angularjs.org/guide/expression) need to be within curly brackets where angular [directives](http://docs.angularjs.org/guide/directive) do not – My Head Hurts Feb 13 '13 at 09:08
7
<script src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script>
<script type="text/javascript">
    function controller($scope) {
        $scope.data = {
            show: true,
            hide: false
        };
    }
</script>

<div ng-controller="controller">
    <div ng-show="data.show"> If true the show otherwise hide. </div>
    <div ng-hide="!(data.hide)"> If true the show otherwise hide.</div>
</div>
Anil Singh
  • 3,818
  • 2
  • 35
  • 46
0

remove {{}} braces around foo.bar because angular expressions cannot be used in angular directives.

For More: https://docs.angularjs.org/api/ng/directive/ngShow

example

  <body ng-app="changeExample">
    <div ng-controller="ExampleController">
    <p ng-show="foo.bar">I could be shown, or I could be hidden</p>
    <p ng-hide="foo.bar">I could be shown, or I could be hidden</p>
    </div>
    </body>

<script>
     angular.module('changeExample', [])
        .controller('ExampleController', ['$scope', function($scope) {
          $scope.foo ={};
          $scope.foo.bar = true;
        }]);
</script>
-1

If you want to show/hide an element based on the status of one {{expression}} you can use ng-switch:

<p ng-switch="foo.bar">I could be shown, or I could be hidden</p>

The paragraph will be displayed when foo.bar is true, hidden when false.

Roberto
  • 3,510
  • 30
  • 26