Using a object on NG-repeat as a filter

I have a multiple select dropdowns which are generated from a JSON file of categories.

I want to use the choice the users make in the selection to filter a list of apps that are generated with an ng-repeat.

I have this plunker which shows the dropdowns generated but the users choice goes into an object and from what i am told you can not use this as a filter for ng-repeat's.

Is it possible to use this to filter by or can i convert this?

This is from an earlier post of mine - Dynamically create multiple dropdowns angularjs from a single JSON file

Here's an alternate version rendering each select individually. It's using a custom groupBy filter (using underscore):

app.filter('groupBy', ['$parse', function ($parse) {
  return function groupByFilter(input, groupByExpr) {
    return _.groupBy(input, $parse(groupByExpr));


<div ng-repeat="(categoryTypeName, categories) in groupedCategories track by categoryTypeName">

    ng-options="c as for c in categories track by"

Unfortunately the filter has to be applied when the the data changes,

$scope.$watchCollection('categories', function (categories) {
  $scope.groupedCategories = groupByFilter(categories, '');

because if used with ng-repeat directly angular will complain about an Infinite $digest Loop.

So is it possible to use the output (users choices) as a filter on the repeat?

What i need to use is the name of the category that is chosen to filter the apps so if the app is not tagged with the category they chose then it wont show up. Each app has the ability to add any tags that are available in the dropdowns.


The list of apps displayed will be handled in the same controller as the filters from above and in the plunker and they will be in the same view, see the image as to what i currently have. Blurred things out for protection. - apologies it's not letting me getting a higher quality screenshot.

The ng repeat i currently have for the apps is;

        <div class="col-md-4"
                            ng-repeat="app in objects | filter:query |orderBy:'-createdAt'">

With query just being a simple search input box.

To generate the dropdowns from which the the user can make multiple choices is using this repeat;

<div ng-repeat="(categoryTypeName, categories) in groupedCategories track by categoryTypeName">
  <select  class="form-control" multiple class="span4 chzn-select" chosen data-placeholder=" "
    ng-options="c as for c in categories track by"


Chosen is just a plugin used to make multiple selection look nice.

Each app that is displayed they can click on and it will give them more details about it. Each app has can have 1 or multiple tags all of which are available to filter by in the dropdown menus which are generated.

As you can see from the image posted the user can filter down by selecting multiple categories from any of the categoryTypes they want. I cant really use the group by as the stakeholders want every filter dropdown to be seperated and then allow the user to choice multiple categories to filter by from 1 or multiple categoryTypes.

The controller i have to generate the apps looks like this;

$scope.objects = [];

  $scope.getData = function (cb) {
            return appFactory.query(function (data) {
                $scope.objects = data;
                if (cb) cb();
            }, function(data) {
                alert("ERROR getting all applications");


var successCallback = function (e, cb) {
        alertService.add("success", "Success!");

cb - is just a succesfull callback which is in the controller

With the factory being;

.factory('appFactory', function ($resource) {
        return $resource(
            { id:'@id' }, 
            { 'update': { method: 'PUT'} }  

What i want to happen is as the user choices filters just like the angularjs text search demo it will filter out the apps each time a selection is made and when the user clicks the x and removes a category from the filter list it will remove any apps that were shown because of that choice. If that makes sense?

I think that is all the information i would need to give, if their is still more i have left out please let me know.

I think you'll again need a custom filter for this. Try for example (again using underscore):

app.filter('bySelectedCategories', [function () {
  return function bySelectedCategoriesFilter(input, selection) {
    var categoryNames = _.flatten(, function (categories) {
      return _.pluck(categories, 'name');

    return _.filter(input, function (app) {
      return _.difference(categoryNames, app.categoryNames).length === 0;

this works by:

  1. getting the selected categoryNames and
  2. filtering the apps by computing the difference to the selected categories