1

i am trying to filter an angular js array using multiple columns .

e.g | filter:{sender: 'fred', reciever: 'josh'} | filter:{sender: 'josh', reciever: 'fred'}

But it doesn't seem to work, please view my complete code below

      <div ng-repeat="msg in messages | filter:{sender: 'fred', reciever: 'josh'} | filter:{sender: 'josh', reciever: 'fred'}">

      Sender : {{ msg.sender }} MSg : {{ msg.msg }} Reciever : {{ msg.reciever }}
      </div>

      </div>

      <script>
      var app = angular.module('myApp', []);
      app.controller('myCtrl', function($scope) {
          $scope.messages = [
      {sender:'fred', reciever:'josh', msg:'HI'},
      {sender:'josh', reciever:'fred', msg:'i DEY'}, 
      {sender:'fred', reciever:'josh', msg:'Hello'}
      ];
      });
      </script>

Here is the js fiddle https://jsfiddle.net/c8uvrbvj/

4
  • creating custom filter would be an great option to go.. by passing property & name to be filter out Commented Mar 26, 2016 at 14:59
  • @PankajParkar, can u give me a sample custom filter that can work for me ? Commented Mar 26, 2016 at 15:04
  • @Meiko The function worked well, but after adding a new value to the array like {sender:'josh', receiver:'racheal', msg:'hw re u?'} , the new values showed up . what i was aiming to achieve is to display the message between where the sender = ''josh' and receiver = "fred" or sender = "fred" and receiver = "josh" . Thanks for your help ... Commented Mar 26, 2016 at 15:49
  • @Meiko The code is running fine , but i am having little issues with passing variables into the filter object <div ng-repeat="msg in (messages | myfilter:[{sender: user1, reciever: user2},{sender: user2, reciever: user1}])"> Commented Mar 26, 2016 at 17:48

1 Answer 1

2

I would prefer to filter the messages in the controller. DOM filters can cause performance problems. see: Using Controller $filters to prevent $digest performance issues

But this basically works:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
    $scope.messages = [
        {sender:'fred', receiver:'josh', msg:'HI'},
        {sender:'josh', receiver:'fred', msg:'i DEY'}, 
        {sender:'josh', receiver:'racheal', msg:'hw re u2?'},
        {sender:'barack', receiver:'angela', msg:'Dear'}, 
        {sender:'fred', receiver:'josh', msg:'Hello'}, 
        {sender:'angela', receiver:'barack', msg:'Moin'},
        {sender:'josh', receiver:'racheal', msg:'hw re u?'}
    ];
}).filter('myfilter', function() {
  return function(input, filter) {
    return input.filter(function(e1){
      return filter.find(function(e2) {
          return e1.sender === e2.sender && e1.receiver === e2.receiver;
      });
    });
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

<div ng-repeat="msg in (messages | myfilter:[{sender: 'fred', receiver: 'josh'},{sender: 'josh', receiver: 'fred'}])">

Sender : {{ msg.sender }} MSg : {{ msg.msg }} Reciever : {{ msg.reciever }}
</div>

</div>

It follows a solution without DOM filtering, I think a better approach:

    var app = angular.module('myApp', []);
    
    function filter(input, filter) {
        return input.filter(function(e1){
            return filter.find(function(e2) {
                return e1.sender === e2.sender && e1.receiver === e2.receiver;
            });
        });
    }
    
    app.controller('myCtrl', function($scope) {
        
        var messages = [
            {sender:'fred', receiver:'josh', msg:'HI'},
            {sender:'josh', receiver:'fred', msg:'i DEY'},
            {sender:'josh', receiver:'racheal', msg:'hw re u2?'},
            {sender:'barack', receiver:'angela', msg:'Dear'},
            {sender:'fred', receiver:'josh', msg:'Hello'},
            {sender:'angela', receiver:'barack', msg:'Moin'},
            {sender:'josh', receiver:'racheal', msg:'hw re u?'}
        ];
        var name1 = 'fred';
        var name2 = 'josh';
        var myFilter = [{sender: name1, receiver: name2},{sender: name2, receiver: name1}];

        $scope.messages = filter(messages, myFilter);
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

    <div ng-repeat="msg in messages">

        Sender : {{ msg.sender }} MSg : {{ msg.msg }} Reciever : {{ msg.reciever }}
    </div>

</div>

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

10 Comments

The function worked well, but after adding a new value to the array like {sender:'josh', receiver:'racheal', msg:'hw re u?'} , the new values showed up . what i was aiming to achieve is to display the message between where the sender = ''josh' and receiver = "fred" or sender = "fred" and receiver = "josh" . Thanks for your help ...
see the edited code... could not reproduce that ... where did you add {sender:'josh', receiver:'racheal', msg:'hw re u?'}?
The code is running fine , but i am having little issues with passing variables into the filter object <div ng-repeat="msg in (messages | myfilter:[{sender: user1, reciever: user2},{sender: user2, reciever: user1}])">
I think you should filter the messages in the controller or in a service. It is much better for your performance and easier to implement. You could use this function "function(input, filter) {..." after giving it a name. I think it does not make sense to do the filtering in the template.
even after using the function in the controller it didn't work with variables , but works well with static values ..
|

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.