Unable to call Object.keys in angularjs

Solution 1:

Yes, That is because Object is a part of window/global and angular cannot evaluate that expression against the scope. When you specify Object.keys in your binding angular tries to evaluate it against the $scope and it does not find it. You could store the reference of object.keys in some utility in rootScope and use it anywhere in the app.

Something like this:-

angular.module('yourApp',[deps...]).run(function($rootScope){
  //Just add a reference to some utility methods in rootscope.
  $rootScope.Utils = {
     keys : Object.keys
  }

  //If you want utility method to be accessed in the isolated Scope 
  //then you would add the method directly to the prototype of rootScope 
  //constructor as shown below in a rough implementation.

  //$rootScope.constructor.prototype.getKeys = Object.keys;

});

and use this as:-

<span class="pull-right"> {{ Utils.keys(stations).length }} Stations</span>

Well this will be available to any child scopes except for isolated scopes. If you are planning to do it on the isolated scope (eg:- Isolated scoped directives) you would need to add the reference of Object.keys on the scope, or as you expose a method on the scope which will return the length.

Or better yet , create a format filter to return the keylength and use it everywhere.

app.filter('keylength', function(){
  return function(input){
    if(!angular.isObject(input)){
      throw Error("Usage of non-objects with keylength filter!!")
    }
    return Object.keys(input).length;
  }
});

and do:-

{{ stations | keylength }}

Demo

Solution 2:

Use the function to determine the number of object properties:

$scope.keyLength = function (obj) {
    return Object.keys(obj).length;
}

and use:

{{ keyLength(myObj) }}

Solution 3:

I think filters are the most AngularJS way of handling structures in template code:

angular.module('app.filters').filter('objectKeysLength', [function() {
    return function(items) {
        return Object.keys(items).length;
    };
}]);

angular.module('app.filters').filter('objectKeys', [function() {
    return function(item) {
        if (!item) return null;
        var keys = Object.keys(item);
        keys.sort();
        return keys;
    };
}]);