Angular filter based on properties I wrote a Angular filter to use filters based on properties that handles some specific properties differently.

Is there a way to improve or use some built-in Angular filter to avoid extra code?

Usage:

&lt;div ng-repeat="item in items | myObjectFilter: { someProp: user.uid, pending: true }"&gt;


Code:

angular.module('app', []).filter('myObjectFilter', function () {
    function _filter(source, search) {
        if (!source) { return source; }

        var result = [], defaultFilters;

        //default filter setting
        defaultFilters = {
            pending: false,
            refusedAt: null
        };

        search = angular.extend({}, defaultFilters, search);

        angular.forEach(source, function (value, key) {
            var isFiltered = true;

            for (var x in search) {
                if (value.hasOwnProperty(x)) {
                    var isEqual = false;

                    // handle specific properties or simply compare
                    switch (x) {
                        case 'someProp':
                        case 'someProp2':
                            isEqual = value[x].uid == search[x];
                            break;
                        default:
                            isEqual = value[x] == search[x];
                            break;
                    };

                    isFiltered = isFiltered &amp;&amp; isEqual;

                    if (!isEqual) {
                        break; //exit loop if filter not passed
                    } 
                }
            }

            if (isFiltered) {
                result.push(value); // add item to filterd result
            }
        });

        return result;
    };

    return _filter;
});
Named functions

I like the idea of named functions. It helps when you debug your app - you are getting error with name of function instead of "anonymous".

Defalt options

The default options location is good place to keep it. Filter has to be independant from controller and should manage its own data. Although, the default options object is created at every reference to filter. This is waste of resources.

angular.module('app', []).filter('myObjectFilter', function myObjectFilter() {
    //default filter setting
    var defaultFilters = {
        pending: false,
        refusedAt: null
    };

    function _filter(source, search) {
        if (!source) { return source; }
        var result = [];
        search = angular.extend({}, defaultFilters, search);
        ...


Last if

This code:


isFiltered = isFiltered &amp;&amp; isEqual;
if(!isEqual) {
    break; //exit loop if filter not passed
}



checks for isEqual two times.

//isFiltered = isFiltered &amp;&amp; isEqual; //you can delete this line
if(!isEqual) {
    isFiltered = false;
    break; //exit loop if filter not passed
}


My version checks it only once. I know that you don't get much performance here, but imagine situation when you would like to change the statement for making isFiltered false. You need to change condition in two places. This can lead to serious headache and long debugging in case one of them is forgotten ;)