0

I cannot properly use my ng-if inside an ng-repeat. I've updated my AngularJS to the newest version (09/27/2014) and I still can not get it to work right. I have code that works fine outside of the ng-repeat and I also have code that works inside ng-repeat fine when I ng-if="vm.detail == false". However ng-if="vm.detail == true" does NOT work. I even have printed the value of vm.detail to the console and it's correct, as it should be. But, the block of code that evaluates ng-if="vm.detail == true" as "true" does NOT execute. It's nuts. Here is my code:

                    <th>Division</th>
                    <th>Pool</th>
                    <th>Subpool</th>
                    <th ng-click="sort.predicate = 'ExperienceGroup.RenewalGroup.Name'; sort.reverse = !sort.reverse">
                        RenewalGroup
                    </th>
                    <th>MCH</th>
                    <th ng-click="sort.predicate = 'ContractNumber'; sort.reverse = !sort.reverse">
                        Contract
                    </th>
                    <th ng-click="sort.predicate = 'PlanCode'; sort.reverse = !sort.reverse">
                        PlanCode
                    </th>

                </tr>

                <!--Search By: Mch, Contract Number, Mcp, PlanCode--> 
                <tr ng-if="vm.detail == true">
                    <th>Trust</th>
                    <th>MCH</th> 
                    <th>Contract</th> 
                    <th>Plan Code</th> 
                    <th>Status Date</th> 
                    <th>Status</th> 
                    <th>Effective Date</th> 
                    <th >MCP</th>
                    <th >Rates</th>
                    <th>State Availability</th>
                </tr>

            </thead>
            <tbody>


                <!--Data for MchNumber, ContractNumber, PlanCode Searches-->
                <tr ng-repeat="vm in vm.Mch2Information" ng-if="vm.detail == 'true'">
                    <!--<th>{{vm.CustomerNumber}}</th>-->
                    <td> {{vm.TrusteeCustNum}}</td>
                    <td>{{vm.CustomerNumber}}</td>
                    <td>{{vm.ContractNumber}}</td>
                    <td>{{vm.PlanCode}}</td>
                    <td>{{vm.PlanStatusDate}}</td>
                    <td>{{vm.PlanStatus}}</td>
                    <td> {{vm.PlanEffectiveDate}}</td>
                    <td>{{vm.Mcp}}</td> <!--Not yet implemented-->
                    <td><a href="">Rates</a></td>
                    <td><a href="">State Availability</a></td>

                </tr>



                <!--Data for Division, Pool, Subpool, and RenewalGroup Searches-->
                <tr ng-repeat="plan in vm.plans  
                    | filter: {MchNumber : planFilter.Mch} 
                    | limitTo: vm.pageSize" ng-if="vm.detail == false">

                    <td>{{plan.ExperienceGroup.RenewalGroup.Subpool.Pool.Division.DivisionName}}</td>
                    <td>{{plan.ExperienceGroup.RenewalGroup.Subpool.Pool.PoolName}}</td>
                    <td>{{plan.ExperienceGroup.RenewalGroup.Subpool.SubpoolName}}</td>
                    <td>{{plan.ExperienceGroup.RenewalGroup.RenewalGroupName}}</td>
                    <td><a href="#/Mch/MCH/{{plan.MchNumber}}">{{plan.MchNumber}}</a></td>
                    <td>{{plan.PlanDesign.ContractNumber}}</td>
                    <td>{{plan.PlanDesign.PlanCode}}</td>
                    <td>{{plan.Mcp}}</td>
                  </tr>

And the controller:

    function getPlans(searchParameters)
    {
        vm.loadingPlans = true; vm.search = searchParameters;
        mchService.searchParameters = searchParameters.MchNumber;
        datacontext.getAssignedPlans(searchParameters, vm.pageSize).then(function (plans)
        {
            vm.plans = plans;

      //Compares which columns are being populated for choosing which headings to show
        if (vm.search.MchNumber != null 
            ||vm.search.ContractNumber != null 
            || vm.search.PlanCode != null)
        {
            vm.detail = true;
            vm.test = !vm.test;
            alert("vm.detail is: " + vm.detail)
            //vm.detail = !vm.detail;
            //If users enter JUST a MCH number then display those results
            if (vm.search.ContractNumber == null & vm.search.PlanCode == null)
            {
                vm.getEntityInformation();
            }

        }

        if (vm.search.DivisionName != null
            || vm.search.PoolName != null
            || vm.search.SubpoolName != null
            || vm.search.RenewalGroupName != null)
        {
            vm.detail = false;
            alert("vm.detail is: " + vm.detail);
           // vm.detail = !vm.detail;
        }

            //Sets values to NULL after every search is performed
       vm.search.MchNumber =
       vm.search.ContractNumber =
       vm.search.PlanCode =
       vm.search.DivisionName =
       vm.search.PoolName =
       vm.search.SubpoolName =
       vm.search.RenewalGroupName = null;

        }).finally(function () { vm.loadingPlans = false; });   
    }
Roham Rafii
  • 2,929
  • 7
  • 35
  • 49
user1789573
  • 515
  • 2
  • 8
  • 23
  • 2
    What about taking the quotes off the true? – Stevo Perisic Sep 29 '14 at 21:19
  • I tried that. I put them in single-quotes to see if there was a difference. I found none. But, good question. – user1789573 Sep 29 '14 at 21:22
  • Too much code to put into Fiddler. However, i do know that ng-if='vm.detail == true || vm.detail == null' does work. Which, says to me there is a null value somewhere. However, the console says different. Could this just be a control-flow issue w/ my DOM? – user1789573 Sep 29 '14 at 21:31
  • Why you're doing `ng-if="vm.detail == true"` instead of just `ng-if="vm.detail"`? Anyway it would help a lot if you showed a working/broken example of your code. – Michał Miszczyszyn Sep 29 '14 at 21:37
  • might be wrong but think `vm` mentioned in `ng-if` is referring to an outer scoped object (not the enumerated object from `ng-repeat`). have you considered using a filter in the `ng-repeat`? – shakib Sep 29 '14 at 21:43
  • My example code does work. However, i have way too much stuff to include if you want an end-to-end model. Suffice it to say: the controller works, and so does getting the data. In fact, actually everything works perfect EXCEPT when i try to evaluate ng-if='vm.detail' ONLY with an ng-repeat. If it's not w/ ng-repeat it evaluates and executes like it should. I'm getting an problem of the code NOT executing...I am using vm.detail == true to show it is explicitly evaluating and not implicitly evaluating. It's a more advanced thing, for sure. – user1789573 Sep 29 '14 at 21:44
  • @shakib: i've considered a filter, however it won't work for my purpose since i'm using vm.detail as a toggle, and not a filter. However, i did read about filters and this wont work in this case, unfortunately. Also, i'm not outside of scope due to debugging and finding that ng-if="!vm.detail" WORKS FINE! But, it shouldn't...that seems like logic, but it isn't a logic problem. Hence, my confusion... – user1789573 Sep 29 '14 at 21:46
  • 2
    there : '' change to td> {{info.TrusteeCustNum}}... – sylwester Sep 29 '14 at 21:59
  • Thank you @sss! This worked for me. Apparently, the alias name being the same name as the scope ($scope) is not allowed...or the interpreter just gets confused. Either way, it's a HUGE pitfall in AngularJS and i think it should be addressed by Google. – user1789573 Sep 30 '14 at 13:13
  • 1
    @user1789573 you're welcome. I will add answer maybe it helps to somebody else in future – sylwester Sep 30 '14 at 13:15

1 Answers1

0

Please update that bit.

<tr ng-repeat="vm in vm.Mch2Information" ng-if="vm.detail == 'true'">
    <!--<th>{{vm.CustomerNumber}}</th>-->
    <td>{{vm.TrusteeCustNum}}</td>
    <td>{{vm.CustomerNumber}}</td>
    <td>{{vm.ContractNumber}}</td>
    <td>{{vm.PlanCode}}</td>
    <td>{{vm.PlanStatusDate}}</td>
    <td>{{vm.PlanStatus}}</td>
    <td>{{vm.PlanEffectiveDate}}</td>
    <td>{{vm.Mcp}}</td>
    <!--Not yet implemented-->
    <td><a href="">Rates</a>
    </td>
    <td><a href="">State Availability</a>
    </td>
</tr>

to :

<tr ng-repeat="info in vm.Mch2Information" ng-if="vm.detail == 'true'">
    <!--<th>{{vm.CustomerNumber}}</th>-->
    <td>{{info.TrusteeCustNum}}</td>
    <td>{{info.CustomerNumber}}</td>
    <td>{{info.ContractNumber}}</td>
    <td>{{info.PlanCode}}</td>
    <td>{{info.PlanStatusDate}}</td>
    <td>{{info.PlanStatus}}</td>
    <td>{{info.PlanEffectiveDate}}</td>
    <td>{{info.Mcp}}</td>
    <!--Not yet implemented-->
    <td><a href="">Rates</a>
    </td>
    <td><a href="">State Availability</a>
    </td>
</tr>
sylwester
  • 16,498
  • 1
  • 25
  • 33
  • Basically, if the Alias name inside the ng-repeat is the same name as the $scope's properties you are trying to access Javascript will attempt to handle it but will mess up during the process. IMHO, this is a control-flow issue that should be addressed by the AngularJS team at Google. Note to Google: "Please, update your stuff accordingly". – user1789573 Sep 30 '14 at 18:08