jeanmarc jeanmarc - 4 months ago 39
AngularJS Question

AngularJS ng-class check if nested key/value pair exists and then add value as class

So, I have this nested array which I can't modify the structure of. I want to check if a key/value pair exists and if it does, add a corresponding class to the element in question.

I have been trying to use a variation of the expression:

ng-class="{ 'active' : data.indexOf('"name":"john"') >= 0 }"


However my expression is a bit more complicated and I'm afraid it's too much to use just like that. There's also the problem of using more than two level nested quotes.

Here's a fiddle using an array with a similar structure to what I'm working with:

http://jsfiddle.net/5tvmL2Lg/2/

HTML:

<body ng-app="myModule">
<div ng-controller="myController">
<div ng-repeat="hero in heroes">
<div ng-class="{ 'weight-\'hero.stats.indexOf('\'type\':\'weight\'').value\'' : hero.stats.indexOf('\'type\':\'weight\'') >= 0 }">
hello
</div>
</div>
</div>
</body>


JS:

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

myModule.controller('myController', ['$scope', function($scope) {

$scope.heroes = [{
"firstname" : "clark",
"lastname" : "kent",
"stats" : [
{
"type" : "height",
"value" : "6'2"
},
{
"type" : "weight",
"value" : 220
},
{
"type" : "hair",
"value" : "brown"
}
]},
{
"firstname" : "bruce",
"lastname" : "wayne",
"stats" : [
{
"type" : "height",
"value" : "6'1"
},
{
"type" : "hair",
"value" : "black"
}
]},
{
"firstname" : "peter",
"lastname" : "parker",
"stats" : [
{
"type" : "height",
"value" : "5'11"
},
{
"type" : "weight",
"value" : 180
},
{
"type" : "hair",
"value" : "auburn"
}
]}];

}]);


In the end the goal would be to add a class named for example "weight-220" for the "clark kent" div, no class for the "bruce wayne" div, and "weight-180" for the peter parker div.

I know my problem is convoluted but any help would be greatly appreciated... :)

Answer

You don't need to add all your code logic into your ng-class. You can make it more complex (to check for the deeply-nested objects) by using a function that returns a string:

<div ng-class="ClassBuilder(hero)">
    hello
</div>

In your controller, add this function:

$scope.ClassBuilder = function(hero) {
    for (var i = 0; i < hero.stats.length; i++) {
        if (hero.stats[i].type == "weight") {
            weight = hero.stats[i].value;
            return "weight-" + hero.stats[i].value;
        }
    }
}

This will receive the hero object from each ng-repeat and check if the weight type exists. If so, it will use the corresponding value to return a string in your requested format, for example: "weight-220". Otherwise, it will return nothing and no class will be applied to that <div>.