angularjs filter based on matching values in nested array

Here is my code. Please run the script to see how it works :

var app = angular.module('myApp', []);

app.controller('listdata', function($scope, $http) {
var data = [{
    "name": "John",
    "queue": [{
        "number": "456",
        "status": "Unavailable"
    },
    {
        "number": "111",
        "status": "Unavailable"
    },
    {
        "number": "201",
        "status": "Paused"
    }],
    "phone": "7411173737"
},
{
    "name": "George",
    "queue": [{
        "number": "111",
        "status": "Paused"
    },
    {
        "number": "456",
        "status": "Unavailable"
    }],
    "phone": "8558855858"
},
{
    "name": "Hilary",
    "queue": [{
        "number": "456",
        "status": "Unavailable"
    }],
    "phone": "5454573737"
},
{
    "name": "Edmond",
    "queue": [{
        "number": "665",
        "status": "Unavailable"
    }],
    "phone": "7454543737"
}];
$scope.a = [];
$scope.users = [];
for(i=0;i<data.length;i++){
    for(j=0;j<data[i].queue.length;j++){
        if(data[i].queue[j].number == 111 || data[i].queue[j].number == 456){
            $scope.a.push(data[i]);
        }
    }
}
$scope.users = $scope.a;
//console.log($scope.users);
   $scope.filter111 = function (user) {
            return (user.queue.find(({number}) => number === '111'));
        }
    $scope.filter456 = function (user) {
           return (user.queue.find(({number}) => number === '456'));
        }
});

app.filter('unique', function() {
   return function(collection, keyname) {
      var output = [],
          keys = [];
      angular.forEach(collection, function(item) {
          var key = item[keyname];
          if(keys.indexOf(key) === -1) {
              keys.push(key);
              output.push(item);
          }
      });
      return output;
   };
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp">

<label class="switch">
  <input type="checkbox" ng-model="queue111">111
</label>
<label class="switch">
  <input type="checkbox" ng-model="queue456">456
</label>
<label class="switch">
  <input type="checkbox" ng-true-value='"Paused"' ng-false-value='' ng-model="paused">Paused
</label>
<div class="row" ng-controller="listdata">

  <div ng-repeat="user in users|filter: queue111? filter111: ''|unique:'name'|filter: queue456? filter456: ''|filter: paused track by $index">
    <p> {{user.name}} {{user.phone}}</p>
  </div>
</div>

</div>

From the above code my data array contains objects which have the name of a user, his phone number and the calling queue he belongs to.

I have four calling queues 111,456,201 and 665 respectively.

One user can be in any number of calling queues. I have filtered the data in controller such that it only shows the users who belong to either queue 111 or queue 456 in the front end.

So from my code the user Edmond belongs to queue 665 hence his details are not displayed in the front end. The other 3 users belong to either 111, 456 or both hence their details are shown in the user panel.

Then filter 111 show's only those users who belong to queue 111. filter 456 will show only those users who belong to queue 456.

Now a user has a status for every queue. The status can be anything like Unavailable, Paused etc.

I have a filter called Paused in the front end as shown in the code and this filter is supposed to output only those user's whose status is Paused in either 111 or the 456 queue only. It should not output the user if his status is not Paused in 111 or 456.

When I click the Paused filter it displays the name John and George. This output is actually wrong because I only want to display those whose status is Paused in either 111 or 456 queue. So in the output the result for George is correct as his status is Paused in the queue 456 but for John the output is wrong as he is not paused in the queue 111 or 456. He's paused in the queue 201 and is still being displayed by the Paused filter which is not the expected output.

Expected output is it should only display data for George as he actually belongs to one of the two queues (111 or 456) and his status is paused in one of the queues (111 or 456) which I'm displaying in the frontend when I click the Paused filter. How do I do this?

Answers:

Answer

I solved the issue by creating a custom function in the controller like this :

$scope.pausedc = function (user) {
          return (user.queue.find(({number,status}) => number === '111' && status === 'Paused' || number === '456' && status === 'Paused'));
      }

and html :

<label class="switch">
  <input type="checkbox"  ng-model="paused">Paused
</label>


<div class="row" ng-controller="listdata">

  <div ng-repeat="user in users| filter:paused? pausedc: '' track by $index">
    <p> {{user.name}} {{user.phone}}</p>
  </div>
</div>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.