angularjsangularjs-ng-repeatng-filter

seach filter inside a parent ng-repeat not working


I have an array of objects which is shown below which I called $scope.parlist. I already did a research so that I can filter my nested ng-repeat whenever the user search for a particular account but I failed

[
   {
      bch: "001",
      loan_product: [
         {
            id_code: "ML1",
            asofmonitoring:[{ //asofmonitoring is fixed to have just one object here
                days07:[
                     {
                       loan_no: "ML-XXX-XXX-XXX",
​​​​​​                       name: "John Papa"
                     },
                     {
                       loan_no: "ML-XXX-XXX-XXX",
​​​​​​                       name: "Grace Papa"
                     }
                     ...
                ],
                days08:[
                     {
                       loan_no: "ML-XXX-XXX-XXX",
​​​​​​                       name: "Earl Papa"
                     },
                     {
                       loan_no: "ML-XXX-XXX-XXX",
​​​​​​                       name: "Britney Papa"
                     }
                     ...
                ]
                ...
            }]
         },
         ...
      ]

   }
   ...
]

html

<tbody data-ng-repeat="par in parlist" ng-init="outerindex = $index">
    <tr>
        <td colspan="15" style="background-color:rgb(233, 236, 239)">
            <table class="table table-sm">
                 <tbody ng-repeat="prod in par.loan_product" ng-init="innerindex = $index">
                      <tr>
                         <table>
                             <tbody ng-if="prod.asofmonitoring[0].days07.length > 0">
                                  <tr>
                                      <td colspan="2" class="text-left table-warning">
                                         <input type="text" ng-model="q7[innerindex]" class="form-control" placeholder="Search account" aria-label="Search account" aria-describedby="basic-addon2">
                                       </td>

                                    </tr>
                               </tbody>
                               <tbody ng-repeat="days07 in prod.asofmonitoring[0].days07 | filter:q7[innerindex]">
                                     <tr>
                                         <td class="text-center" ng-bind="days07.loan_no">loading...</td>
                                     </tr>
                               </tbody>
                          </table>
                       </tr>
                   </tbody>
             </table>
         </td>
      </tr>
</tbody>

My problem is I can't make the search filter to work in my ng-repeat="days07 in prod.asofmonitoring[0].days07 ng-repeat. I already make the other suggestion like putting a ng-init="outerindex = $index" and other solution but my ng-repeat wont filter. Can anybody help me out with this problem?


Solution

  • You've got a scope-related binding issue here.

    Both ng-if and ng-repeat implicitly create new scopes.

    You've not included any controller code but I think I'm making a fair assumption that you've not explicitly defining q7. Consequently, when q7 appears inside the ng-if, only this scope will be able to access the bound model. The ng-repeat is on a sibling element and thus doesn't have the same visibility, which is why nothing happens when you change the text filter model.

    Quick solution here would be to explicitly initialise q7 in your controller to ensure no variable shadowing occurs.

    Included a stripped down example below for you:

    Edit: Updated to reflect commentary.

    angular
      .module('app', [])
      .controller('ctrl', function ($scope) {
        // Explicitly declare text filter model so `ng-repeat` does not create shadowed copies
        $scope.q = {};
        $scope.parlist = [
          {
            bch: '001',
            loan_product: [
              {
                id_code: 'ML1',
                asofmonitoring: [
                  {
                    days07: [
                      {
                        loan_no: 'ML-XXX-XXX-XXX',
                        name: 'John Papa',
                      },
                      {
                        loan_no: 'ML-XXX-XXX-XXX',
                        name: 'Grace Papa',
                      },
                    ],
                    days08: [
                      {
                        loan_no: 'ML-XXX-XXX-XXX',
                        name: 'Earl Papa',
                      },
                      {
                        loan_no: 'ML-XXX-XXX-XXX',
                        name: 'Britney Papa',
                      },
                    ],
                  },
                ],
              },
            ],
          },
          {
            bch: '002',
            loan_product: [
              {
                id_code: 'ML1',
                asofmonitoring: [
                  {
                    days07: [
                      {
                        loan_no: 'ML-XXX-XXX-XXX',
                        name: 'John Papa',
                      },
                      {
                        loan_no: 'ML-XXX-XXX-XXX',
                        name: 'Grace Papa',
                      },
                    ],
                    days08: [
                      {
                        loan_no: 'ML-XXX-XXX-XXX',
                        name: 'Earl Papa',
                      },
                      {
                        loan_no: 'ML-XXX-XXX-XXX',
                        name: 'Britney Papa',
                      },
                    ],
                  },
                ],
              },
            ],
          },
        ];
      });
    <div ng-app="app" ng-controller="ctrl">
      <div ng-repeat="par in parlist">
        <div ng-repeat="prod in par.loan_product">
          <div ng-if="prod.asofmonitoring[0].days07.length">
            <input type="text" ng-model="q[par.bch][$index]" placeholder="bch: {{par.bch}}">
          </div>
          <div ng-repeat="days07 in prod.asofmonitoring[0].days07 | filter:q[par.bch][$index]">
            <div ng-bind="days07.loan_no">loading...</div>
          </div>
        </div>
      </div>
      <pre>q = {{ q | json }}</pre>
    </div>
    <script src="https://unpkg.com/angular@1.7.5/angular.min.js"></script>