Why am I getting different results from ng-show="!emptyArray" and ng-hide="emptyArray"?

25,752

Solution 1

Because [] !== false. You can coerce the length value to boolean instead with !!.

<div ng-hide="!!emptyArray.length">emptyArray is falsy, so do not hide this.</div>
<div ng-show="!!!emptyArray.length">!emptyArray is truthy, so show this.</div>

Edited:

AngularJS's directive hide or show depends on the function toBoolean() for evaluating the value passed in. Here is the source code of toBoolean():

function toBoolean(value) {
  if (value && value.length !== 0) {
    var v = lowercase("" + value);
    value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
  } else {
    value = false;
  }
  return value;
}

And you can verify the following code in JS console:

>var emptyArray = [];
>toBoolean(emptyArray)
false
>toBoolean(!emptyArray)
false

That explains why. Since when emptyArray is passed to the toBoolean() directly, it evaluates the correct result false. However when !emptyArray is passed to toBoolean(), it doesn't evaluate to true since !emptyArray is false itself.

Hope it helps.

Solution 2

ng-if and ng-show mistreats "[]" (empty array)

See: this link

[] == true
false

 [] != true
 true

(![]) == true
false

[''] == true
false

(!['']) == true
false

"" == true
false

"[]" == true
false

(!"[]") == true
false

Sounds its by design.

Share:
25,752

Related videos on Youtube

tamakisquare
Author by

tamakisquare

Updated on March 10, 2020

Comments

  • tamakisquare
    tamakisquare over 4 years

    I have always thought ngShow and ngHide act as boolean counterpart to each other. That belief, however, is shaken by the unexpected behaviour of ngShow when an empty array is involved.

    Here is a demo plunker. Why isn't ng-show="!emptyArray" behaving like ng-hide="emptyArray"?

  • tamakisquare
    tamakisquare almost 11 years
    but emptyArray is defined as []. See the attached plunker.
  • tamakisquare
    tamakisquare almost 11 years
    ng-hide="someArray" works as expected, regardles someArray.length is zero or greater than zero. My concern here is on the behaviour pattern difference between ngShow and ngHide. ngHide seems to work fine without explicitly using length but not in the case of ngShow.
  • tamakisquare
    tamakisquare almost 11 years
    My question is not so much about the how. I am looking for the rationale behind the behaviour difference between ng-hide="someArray" and ng-show="!someArray". ngHide seems to work perfectly regardless someArray is empty or not. But I don't see the same for ngShow.
  • Maxim Shoustin
    Maxim Shoustin almost 11 years
    see my description I posted, + link
  • zs2020
    zs2020 almost 11 years
    @tamakisquare Updated the answer. Hope it helps. Thx.