Checking if object is empty, works with ng-show but not from controller?

I have a JS object declared like so

$scope.items = {};

I also have a $http request that fills this object with items. I would like to detect if this item is empty, it appears that ng-show supports this... I enter

ng-show="items"

and magically it works,I would also like to do the same from a controller but i can't seem to get it to work, it appears I may have to iterate over the object to see if it has any properties or use lodash or underscore.

Is there an alternative?

I did try

alert($scope.items == true);

but it always returns false , when the object is created and when populated with $http, so its not working that way.


Solution 1:

Or you could keep it simple by doing something like this:

alert(angular.equals({}, $scope.items));

Solution 2:

In a private project a wrote this filter

angular.module('myApp')
    .filter('isEmpty', function () {
        var bar;
        return function (obj) {
            for (bar in obj) {
                if (obj.hasOwnProperty(bar)) {
                    return false;
                }
            }
            return true;
        };
    });

usage:

<p ng-hide="items | isEmpty">Some Content</p>

testing:

describe('Filter: isEmpty', function () {

    // load the filter's module
    beforeEach(module('myApp'));

    // initialize a new instance of the filter before each test
    var isEmpty;
    beforeEach(inject(function ($filter) {
        isEmpty = $filter('isEmpty');
    }));

    it('should return the input prefixed with "isEmpty filter:"', function () {
          expect(isEmpty({})).toBe(true);
          expect(isEmpty({foo: "bar"})).toBe(false);
    });

});

regards.

Solution 3:

Use an empty object literal isn't necessary here, you can use null or undefined:

$scope.items = null;

In this way, ng-show should keep working, and in your controller you can just do:

if ($scope.items) {
    // items have value
} else {
    // items is still null
}

And in your $http callbacks, you do the following:

$http.get(..., function(data) {
    $scope.items = {
        data: data,
        // other stuff
    };
});

Solution 4:

another simple one-liner:

var ob = {};
Object.keys(ob).length // 0

Solution 5:

If you couldn't have the items OBJ equal to null, you can do this:

$scope.isEmpty = function (obj) {
    for (var i in obj) if (obj.hasOwnProperty(i)) return false;
    return true;
};

and in the view you can do:

<div ng-show="isEmpty(items)"></div>

You can do

var ob = {};
Object.keys(ob).length

Only if your browser supports ECMAScript 5. For Example, IE 8 doesn't support this feature.

See http://kangax.github.io/compat-table/es5/ for more infos