user2499325 user2499325 - 6 months ago 37
AngularJS Question

Expression in ng-if of AngularJS

Consider the following snippet

ng-if not working

<div class="row">
<div class="col-md-8">
<ul>
<li ng-repeat="bigL in bigLs">
<span ng-if="isObj(bigL)">{{bigL.note}}</span>
<ul ng-if="bigL instanceof Array">
<li ng-repeat="bigLl in bigL">
{{bigLl}}
</li>
</ul>
</li>
</ul>
</div>
</div>


ng-if working

<div class="row">
<div class="col-md-8">
<ul>
<li ng-repeat="bigL in bigLs">
<span ng-if="isObj(bigL)">{{bigL.note}}</span>
<ul ng-if="isArr(bigL)">
<li ng-repeat="bigLl in bigL">
{{bigLl}}
</li>
</ul>
</li>
</ul>
</div>
</div>


Controller

$scope.isArr = function(bigL){
return bigL instanceof Array;
};


I use ng-if to determine whether a nested ul is required to create (by determinate different data type inside the array bigLs), I come to a situation that ng-if cannot evaluate bigL instanceof Array, I then move this snippet inside a function, with the same context, the ng-of works properly, but still cannot understand why it is a need to wrap the expression inside a function instead of running it directly inside the ng-if.

Appreciate for any clarification, thanks!

Answer

I'm not exactly sure of the problem, but there are several things that have bad smells in your code:

Don't use 'instanceof Array', ever. It won't work in an angular expression.

Instead, use angular.isArray(). This will only work in javascript by adding a method to your scope.

So, you would want to do something like this:

Controller:

...
$scope.hasChildren = function(bigL1) {
  return angular.isArray(bigL1);
} 

Template:

 ...
 <ul ng-if="hasChildren(bigL)">
 ...

As a bonus, it becomes much easier to unit test this code.