0

I've been trying to implement filtering JS Map Object (array indexed by an id) instead of the usual js array in angularJS.

For illustration, below is a slight modification of the filtering example as provided in the AngularJS docs.

http://plnkr.co/edit/bNzePyuAAmP6Nl6hj5bI?p=preview

I have converted the input array (friends) to a JSON object with each initial array element mapped as individual keyed element. This modification can be understood below:

Initial (as shown in AngularJS docs):

friends = [{name:'John', phone:'555-1276'},
           {name:'Mary', phone:'800-BIG-MARY'},
           {name:'Mike', phone:'555-4321'},
           {name:'Adam', phone:'555-5678'},
           {name:'Julie', phone:'555-8765'}]

Modified:

friends = {1:{name:'John', phone:'555-1276'},
           2:{name:'Mary', phone:'800-BIG-MARY'},
           3:{name:'Mike', phone:'555-4321'},
           4:{name:'Adam', phone:'555-5678'},
           5:{name:'Julie', phone:'555-8765'}}

Can someone provide a way to filter such an input as part of the ng-repeat directive filter expression. I understand that 'friends' is no longer an array but an object, however since ng-repeat directive is working on this object, perhaps there is a way to filter it as well?

Thanks.

3
  • Why did you modify the original version? It is much easier to work with than the modified version. Commented Jun 18, 2013 at 20:08
  • @TravisJ: I understand it is easier to work with the original version, given the filtering service. However, the reason I create a map instead of an array is for ease of access to each of the objects. For eg, accessing the element with name 'John' in friends array can be a lot easier in a map where all you got to do is say friends[1]. I need such easy access capability in my application. Commented Jun 18, 2013 at 20:14
  • I disagree it is easier to access the elements when it is a map. If it is an array you can use that exact same syntax, except it is zero based. Commented Jun 19, 2013 at 1:52

1 Answer 1

1

jsFiddle Demo - modified json structure

jsFiddle Demo - original json structure

This example maybe be very strong for your small sample, but as your sample becomes more complex this will still handle the filtering.

Use a recursive function to find the object. Originally posted by me here: https://stackoverflow.com/a/11657379/1026459

function ContainsKeyValue( obj, key, value ){
 if( obj[key] === value ) return true;
 for( all in obj )
 {
    if( obj[all] != null && obj[all][key] === value ){
        return true;
    }
    if( typeof obj[all] == "object" && obj[all]!= null ){
        var found = ContainsKeyValue( obj[all], key, value );
        if( found == true ) return true;
    }
 }
 return false;
}

You can leverage this function with or without modification of the original structure you had.

var friends = {1:{name:'John', phone:'555-1276'},
       2:{name:'Mary', phone:'800-BIG-MARY'},
       3:{name:'Mike', phone:'555-4321'},
       4:{name:'Adam', phone:'555-5678'},
       5:{name:'Julie', phone:'555-8765'}};

var filteredFriends = [];
for( var friend in friends )
{
 if( ContainsKeyValue( friends[friend], "name", "John" ) === true )
 {
    filteredFriends.push( friends[friend] );//or directly use the john object here
 }
}
console.log(filteredFriends);//this will contain an array of friends named John.
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Travis. I can probably construct a custom filter that employs the methods provided by you and it would work out just fine. Although I was looking for something less verbose. For now what I have done is to use $scope.friends as a 'MAP' as my model and use the underscoreJS lib function _.values() on this map to bind it to another variable that holds same data as JS array. This is then used in the ng-repeat directive. What I get out of this is that I can use regular filter behavior, as well as use the MAP to easily access my model. $scope ensures that changes in MAP reflect in JS array.

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.