Zoef
Zoef

Reputation: 403

AngularJS - Check if subarray contains something

I have a list of classrooms with each a subarray of actions to be done to the classroom.

{
"id": 1,
"name": "GR302",    
"actions": [
  {
    "date": "19/04/2011",        
    "deadline": "21/04/2011",
    "priority": "high"
  },
  {
    "date": "15/01/2012",        
    "deadline": "20/12/2014",
    "priority": "low"
  }
],

}

I made a list with ng-repeat: room in rooms and in there another ng-repeat: action in room.actions. Now I'd love to place a flag next to the name of the room where there is an action with high priority. But I have no idea how, I'm a beginner with AngularJS. The only thing I could think of is using ng-model & ng-class?

<h4>{{room.name}} <span class="glyphicon" ng-class="(something) ? 'glyphicon-flag' : ''"></span></h4>

Upvotes: 0

Views: 232

Answers (1)

PSL
PSL

Reputation: 123739

You could do it in a lot of different ways, ng-class is flexible enough to take a range of expressions, object, array and string.

You could do:-

 ng-class="{'glyphicon-flag' : action.priority == 'high'}"

Or

 <!--More flexible version, Here you can add more key value pairs if you need to specify different classes for different priority-->
 ng-class="{'high' : 'glyphicon-flag'}[action.priority]" 

Or

 ng-class="{true, 'glyphicon-flag'}[action.priority == 'high']"

Or even with the expression

  ng-class="action.priority == 'high' ?  'glyphicon-flag' : ''"

If you want to do this one level above then:

In your controller create a function on the scope:

 $scope.isFlagged = function(actions){
    if(!angular.isArray(actions)) return false;

    return actions.some(function(action){
       return action.priority === 'high';
    });
 }

and in your view just do:-

ng-class="{true, 'glyphicon-flag'}[isFlagged(room.actions)]"

Or if the number of actions does not change dynamically in your case for every room then you should just add a property in your controller while setting up the view model for rooms, which will be more performance effective.

Example:-

angular.forEach($scope.rooms , function(room) {
    room.isFlagged = isFlagged(room.actions); //Add a property on the room object
});

function isFlagged(actions){
    if(!angular.isArray(actions)) return false;

    return actions.some(function(action){
       return action.priority === 'high';
    });
 }

and just use the flag in your ng-class expression.


The result of the evaluation can be a string representing space delimited class names, an array, or a map of class names to boolean values. In the case of a map, the names of the properties whose values are truthy will be added as css classes to the element.

Also see Array.some and its shim for older browsers.

Upvotes: 1

Related Questions