title: How do I access Object.keys(object).length from a directive template?
body: <p>I'm trying to create a directive that will list all the errors contained in an errors object (<code>{phone: ["is required"]</code>}, but <strong>only if the object is non-empty</strong>.  (It doesn't make sense to say "The following errors…" when there were none.)</p>
  
  <p>I figured out how to check if an object is empty by testing <code>Object.keys(errors).length</code>.  <strong>The problem is that I can't figure out how to access Object.keys from my directive template.</strong>  Is this possible?</p>
  
  <p>Since Angular expressions are "evaluated" (using <code>$parse</code>, not <code>eval()</code> ) in the context of a <code>scope</code> instead of in the context of <code>window</code>, we don't have access to things like <code>Object</code> from the directives template, because <code>Object</code> isn't a property of the scope. (Docs: <a href="http://docs.angularjs.org/guide/expression" rel="noreferrer">Expressions</a>)</p>
  
  <p>Makes sense so far.  It goes on to say that "Unlike JavaScript, where names default to global <code>window</code> properties, Angular expressions must use <code>$window</code> explicitly to refer to the global <code>window</code> object. For example, if you want to call <code>alert()</code> in an expression you must use <code>$window.alert()</code>. </p>
  
  <p>But I can't seem to access <code>Object</code> even if I do <code>$window.Object</code>.  What am I missing?</p>
  
  <hr>
  
  <p>Here's the code for the directive I'm debugging (and here's a <a href="http://jsfiddle.net/TylerRick/hNQq3/2/" rel="noreferrer">jsfiddle</a>):</p>
  
  <p>app.js.coffee:</p>
  
  <pre class="lang-js prettyprint-override"><code>…
  .directive 'displayErrorsAllKeys', -&gt;
    {
      restrict: 'A',
      scope: {
        errors: '='
        debug: '@debug'
      }
      templateUrl: 'templates/display-errors-all-keys'
    }
  
  .run(['$rootScope', ($rootScope) -&gt;
    $rootScope.nonEmpty = (object) -&gt;
      !! Object.keys(object).length
  ])
  
  .controller('TestDisplayErrorsAllKeys',
  ['$scope',
  ( $scope ) -&gt;
  
    $scope.other_errors = {}
  
    $scope.add_errors = -&gt;
      $scope.other_errors = {"surname":["is required"],"phone":["is required"]}
  
    $scope.clear_errors = -&gt;
      $scope.other_errors = {}
  ])
  </code></pre>
  
  <p>display-errors-all-keys.ngt.haml:</p>
  
  <pre class="lang-haml prettyprint-override"><code>.errors(ng-show="$window.Object.keys(errors).length &gt; 0")
    %p The following errors prevented this from saving:
    %div(ng-repeat="(key, error_messages) in errors") {{key}}: {{error_messages | toSentence}}
  </code></pre>
  
  <p>test_ng_display-errors-all-keys.html.haml</p>
  
  <pre class="lang-haml prettyprint-override"><code>:scss
    .errors {
      color: red;
    }
  
  %div(ng-app='MyApp')
    %form(ng-controller="TestDisplayErrorsAllKeys")
      %p errors: {{ other_errors }}
      %p nonEmpty(other_errors): {{ nonEmpty(other_errors) }}
      %hr/
  
      %div(display-errors-all-keys errors="other_errors")
  
      %input(type="button" value="Add errors" ng-click="add_errors()")/
      %input(type="button" value="Clear errors" ng-click="clear_errors()")/
  </code></pre>
  
  <p>I finally got it to work by defining a helper method in my scope and calling that instead (<code>$root.nonEmpty(errors)</code>) (see <a href="http://jsfiddle.net/TylerRick/hNQq3/2/" rel="noreferrer">jsfiddle</a> for working demo).</p>
  
  <p>This is probably a <em>pretty</em> good solution, but:</p>
  
  <ol>
  <li><p>Is there an even better way to solve this?  How would you have done it (written the <code>ng-show</code> expression)?</p></li>
  <li><p>How would I get it to work using <code>Object.keys(errors).length</code> directly in the <code>ng-show</code>??</p></li>
  </ol>