0

I am following this approach to filter nested json response. I have a nested property like this:

instances:{
     instance:[
     {cname:'name1', location:'pa', price:40, model:'2014' },     
     {cname:'name1', location:'ga', price:30 , model:'2014'},
     {cname:'name1', location:'ga', price:20, model:'2010' }        
    ]}

I can filter by top level properties using the above mentioned example but not the child properties. I have modified above example to show nested properties of my json here.http://jsfiddle.net/jackAndy/qygL2m01/4/. I am new to angularjs.

1

1 Answer 1

1
  1. First of all - why You use instances.instance? It it not principally, use players.instances = [];
  2. Use Group functions only 1 time after data loading; Watching filters - it's not necessary in this case;

Function for get filters values (I use underscore uniq function, You can use Your own algorithm for this):

$scope.getFieldsValues = function(field){
    var result = [];
    for(var i = 0; i < $scope.players.length; i++){
        result.push($scope.players[i][field]);
    }
    return _.uniq(result);
};

Filter for players:

$scope.testFl = function(el){
    for(var filter in $scope.filters){
        var filterArray = [];
        for(var i in $scope.filters[filter]){
            if($scope.filters[filter][i]) filterArray.push(i);
        }

        //You can make array with instances properties & compare with it;
        if(filter === 'location'){
            if(el.instances && el.instances.length > 0){
                var intersection = el.instances.filter(function(n) {
                    return filterArray.indexOf(n[filter]) != -1
                });
            } else if(filterArray.length > 0){return false;}
        } else {
            if(filterArray.length > 0 && filterArray.indexOf(el[filter]) === -1) return false;
        }

    }
    return true;
};

Template:

<li ng-repeat="player in players | filter:testFl" >

Filter for instances:

$scope.testFl2 = function(el){
    var filterArray = [];
    for(var i in $scope.filters.location){
        if($scope.filters.location[i]) filterArray.push(i);
    }
    return filterArray.length > 0 && filterArray.indexOf(el.location) === -1 ? false : true;
};

Template:

<span ng-repeat="loc in player.instances | filter:testFl2" >

Fiddle for this;

UPDATE:
Function for count:

$scope.getCount = function(field, value){
    var obj = {};
    obj[field] = value;
    return _.where($scope.players, obj).length;
};

Update fiddle - update underscore, add count function;

I hope this will help you;

For answer were used:
Add underscore to jsfiddle;
variable property name in where underscore.js;

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the solution. I have instance inside instances and it is xml response from a web service. I cannot change web service. I am converting response to json using xml2json. This is xml structure that I am receiving:<Player> <Name>string</Name> <Shirt>string</Shirt> <Instances><Instance>Location>string</Location> </Instance><Instance><Location>string</Location></Instance></Instances></Player>
@Jacky sad, but not critical. Just change all instances ti instances.instance & add xxx.instances && to check of existence; jsfiddle update;
Good solution, marked it as solution.I am having a strange issue. When I filter for single new instance of a location, It is showing all instances where location is null. For example, When I filter with "la" it is showing two extra results.link
@Jacky OK. My English is not understood allow me to tell you the theoretical part. You must add testFl2 to testFl1 if filter === 'location'; This code need refactoring but it working;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.