Often times the choice between both directives seems trivial, because you can achieve the same effect either way. However both have interesting default behaviours that you can use to you advantage.
ng-show
will hide the element it is on by default, unless the condition in it evaluates to true.ng-hide
will show the element it is on by default, unless the condition in it evaluates to true.
This is most useful when your controller is doing AJAX calls or something else that's asynchronous. Your variables may still be undefined until the AJAX call returns.
foo.controller.js
$ctrl.foos;
//...
$http.get('get/all/foos').then(function(response) {
$ctrl.foos = response.data; //Assume that this will be an array
});
Above we can see that the controller requests a value for foos
from the server. The value of foos
will be undefined until the AJAX returns.
foo.template.html
<p ng-show="$ctrl.foos.length <= 0">
No FOOs have been found
</p>
Above we want the message to show only after the AJAX is done and it returned an empty array. Otherwise it should be hidden.
If you think about the condition $ctrl.foos.length <= 0
you will realise that this will throw an exception if $ctrl.foos
is undefined. So you may be tempted to do additional checks, such as $ctrl.foos && $ctrl.foos.length <= 0
to prevent an error to be thrown. However this may open the door to even more unexpected border-line bugs, such as what if foos
has the value "banana". Instead we can make clever use of ng-show
's default behaviour.
Recall that the default behaviour for ng-show
is that it will hide the element unless the condition in it evaluates to true. So in this case we can just use ng-show="$ctrl.foos.length <= 0"
and we will know that the element will be hidden if the AJAX hasn't returned yet or if $ctrl.foos
is a weird value.