6

I'm trying to display a div if an object is non-empty. Using this answer, Im trying to use angular.equals to check emptyness, but its not behaving as expected

var test = angular.module('test',[]);

test.controller('testCtrl', ['$scope', function($scope){
  $scope.foo={};
  $scope.bar="bam"
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
  <div ng-controller="testCtrl">
    <div ng-show="!angular.equals(foo,{})">{{bar}}</div>
  </div>
</div>

The expectation here is that the value of bar will only show if foo is not equal to an empty object. However, foo is clearly set to {} and yet bar still shows.

Community
  • 1
  • 1
David says Reinstate Monica
  • 19,209
  • 22
  • 79
  • 122

4 Answers4

10

If you want to access the angular object from templates or expressions, you have to make it available on the scope of where you want to use it. In this case you can put it on the testCtrl's scope.

var test = angular.module('test',[]);

test.controller('testCtrl', ['$scope', function($scope){
  $scope.angular = angular;
  $scope.foo={};
  $scope.bar="bam"
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
  <div ng-controller="testCtrl">
    <div ng-show="!angular.equals(foo,{})">{{bar}}</div>
  </div>
</div>

I generally put utility objects on $rootScope, so they're available from everywhere.

Philipp Gayret
  • 4,870
  • 1
  • 28
  • 34
  • Can you access rootscope from an angular expression? – David says Reinstate Monica Nov 14 '14 at 15:34
  • 2
    @DavidGrinberg you can access anything defined on the rootscope from an angular expression, plus all other scopes inherit from the rootscope. If you change the JS to do `$rootScope.angular = angular;` the example in the answer will behave the same. – Philipp Gayret Nov 14 '14 at 15:41
6

A cleaner way would be to only add the angular equals method to the $scope:

var test = angular.module('test',[]);

test.controller('testCtrl', ['$scope', function($scope){
   $scope.angularEquals = angular.equals;
}

Then you can use the equals method in the template, like:

<div ng-show="!angularEquals(foo,{})">{{bar}}</div>
Bennie Krijger
  • 595
  • 7
  • 10
  • Any downside of this? I mean, why isn't it available already since it seems so common? – Davi Lima Jan 05 '17 at 13:46
  • No, no downside. The Angular equals method is not added to the scope by default, to keep the scope small and most of the time the javascript equals suffices. – Bennie Krijger Jan 06 '17 at 09:03
4

Your view is looking for a function on the scope, and $scope.angular.equals does not exist. You need to write one like this:

var test = angular.module('test', []);

test.controller('testCtrl', ['$scope',
  function($scope) {
    $scope.foo = {};
    $scope.bar = "bam";
    $scope.isEmpty = function(obj) {
      return angular.equals(obj,{});
    };
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
  <div ng-controller="testCtrl">
    <div ng-hide="isEmpty(foo)">{{bar}}</div>
  </div>
</div>
Blazemonger
  • 90,923
  • 26
  • 142
  • 180
-1

Angular functions can't be used inline, AFAIK. You could do the equal check with a function inside the controller instead and return the result.

Viktor
  • 257
  • 1
  • 5