1

I want to check the state of a property (true or false), on each object to determine weather or not to display a div.

For example, the following works great. Show "Student" heading if students.length > 0, then greet each student by name individually.

<div ng-if="ctrl.classroomInfo.students.length > 0">
  <h1>Students</h1>
  <ul>
    <li ng-repeat="student in ctrl.classroomInfo.students">
      Welcome, {{student}}!
    </li>
  </ul>
</div>

But what if I wanted to add another condition? I only want to show this classroomInfo <div> if atleast one student has good grades.

 <div ng-if="ctrl.classroomInfo.students.length > 0 &&
   ctrl.classroomInfo.students[$index].hasGoodGrades === true">
      <h1>Students</h1>
      <ul>
        <li ng-repeat="student in ctrl.classroomInfo.students">
          Welcome, {{student}}!
        </li>
      </ul>
    </div>

In the above code block I have added students[$index].hasGoodGrades === true, but $index only works in combination with ng-repeat. Meaning I would need to add:

ng-repeat="student in ctrl.classroomInfo.students" to my div tag. This is bad because it will repeat the <h1>Students</h1> header for each student with good grades.

How can I access the hasGoodGrades property on each student object to determine weather or not to show this entire div?

UPDATE:

Thanks for the answers regarding filters. How do I handle a case where the filtered property is another level deep? For example:

ctrl.classroomInfo.students.RESULTS.hasGoodGrades

ng-if="(ctrl.classroomInfo.students | filter:{RESULTS.hasGoodGrades:true}).length > 0" doesn't work

2
  • You'd do it within the li for each student. It doesn't make any sense to put it where you've put it, as that's outside the loop. Commented Aug 24, 2016 at 17:38
  • 2
    to answer the question about the nested filter property try this filter:{ RESULTS: { hasGoodGrades:true }} src - stackoverflow.com/a/32994920/1121919 Commented Aug 24, 2016 at 20:49

4 Answers 4

2

Use a filter:

<div ng-if="(ctrl.classroomInfo.students | filter:{hasGoodGrades:true}).length > 0">
Sign up to request clarification or add additional context in comments.

2 Comments

How does this work when the property is chained another level deep? For example ctrl.classroomInfo.students.results.hasGoodGrades would the filter be written as | filter:{results.hasGoodGrades:true} or is that wrong? Asking because that didn't work for me
@bruh I think in case of nested properties you need to provide a function (instead of an object) as your filter expression. See docs.angularjs.org/api/ng/filter/filter for argument details.
2

You can achieve this either by creating a filter that returns a boolean OR a controller method that returns a boolean. I advocate using a filter to keep your view controllers DRY.

.filter( 'hasGoodGrades', [
    function(){
        return function( students ){
            if( students && students.length )
            {
                 var i = 0, m = students.length, student
                 for( i; i < m; i++ )
                 {
                      student = students[ i ]
                      if( student.hasGoodGrades )
                           return true
                 }
            }

            return false
        }
    }
])

Use the filter in your ng-if like this:

 <div ng-if="ctrl.classroomInfo.students | hasGoodGrades">

EDIT

I'll leave the answer here as an alternative to the other answer. Mine is a little more explicit and more readable, but I think I prefer @jstell's answer better - https://stackoverflow.com/a/39129784/1121919

1 Comment

Thanks for this. I will need to refactor to a solution like this, once I get it working with one of the other inline responses.
0

You can use a filter in your ng-if or ng-show condition, like this:

    <div ng-show="(ctrl.classroomInfo.students | filter:filter(condition)).length">

      <div ng-repeat="student in ctrl.classroomInfo.students">
        {{student.name}}
      </div>
    </div>

Comments

0

To do the test inside the loop:

<div ng-if="ctrl.classroomInfo.students.length > 0">
   <h1>Students</h1>
      <ul>
        <li ng-repeat="student in ctrl.classroomInfo.students">
          <span ng-if="student.hasGoodGrades === true">Welcome, {{student}}!</span>
       </li>
     </ul>
</div>

but the structure for each class will be created...

2 Comments

This will still show the classroomInfo div if no students have good grades.
"but the structure for each class will be created..." so yes.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.