[angular] Dynamic classname inside ngClass in angular 2

I need to interpolate a value inside of an ngClass expression but I can't get it to work.

I tried these solution which are the only ones that makes sense to me, these two fails with the interpolation:

<button [ngClass]="{'{{namespace}}-mybutton': type === 'mybutton'}"></button>
<button [ngClass]="{namespace + '-mybutton': type === 'mybutton'}"></button>

This one works with the interpolation but fails with the dynamically added class because the entire string gets added as a class:

<button ngClass="{'{{namespace}}-mybutton': type === 'mybutton'}"></button>

So my question is how do you use dynamic classnames in ngClass like this?

This question is related to angular

The answer is


Here's an example of something I'm doing for multiple classes with multiple conditions:

[ngClass]="[variableInComponent || !anotherVariableInComponent ? classes.icon.large : classes.icon.small, editing ? classes.icon.editing : '']"

where:
classes is an object containing strings of various classnames. e.g. class.icon.large = "app__icon--large"

It's dynamic! Updates as the conditions update.


This one should work

<button [ngClass]="{[namespace + '-mybutton']: type === 'mybutton'}"></button>

but Angular throws on this syntax. I'd consider this a bug. See also https://stackoverflow.com/a/36024066/217408

The others are invalid. You can't use [] together with {{}}. Either one or the other. {{}} binds the result stringified which doesn't lead to the desired result in this case because an object needs to be passed to ngClass.

Plunker example

As workaround the syntax shown by @A_Sing or

<button [ngClass]="type === 'mybutton' ? namespace + '-mybutton' : ''"></button>

can be used.


Is basically duplication of the other answers - but I didn't get it completely. maybe someone will finally understand it with this example now.

[ngClass]="['svg-icon', 'recolor-' + recolor, size ? 'size-' + size : '']"

will result for e.g. in

class="svg-icon recolor-red size-m"

more elegant solution is to use && (using NgFor and its first, its free to use ur own matching tho):

    <div 
        *ngFor="let day of days;
                let first = first;"
        class="day"
        [ngClass]="first && ('day--' + day)"
    </div>

will turn out as:

class="day day--monday"

  <div *ngFor="let celeb of singers">
  <p [ngClass]="{
    'text-success':celeb.country === 'USA',
    'text-secondary':celeb.country === 'Canada',
    'text-danger':celeb.country === 'Puorto Rico',
    'text-info':celeb.country === 'India'
  }">{{ celeb.artist }} ({{ celeb.country }})
</p>
</div>

i want to mention some important point to bare in mind while implementing class binding.

    [ngClass] = "{
    'badge-secondary': somevariable  === value1,
    'badge-danger': somevariable  === value1,
    'badge-warning': somevariable  === value1,
    'badge-warning': somevariable  === value1,
    'badge-success': somevariable  === value1 }" 

class here is not binding correctly because one condition is to be met, whereas you have two identical classes 'badge-warning' that may have two different condition. To correct this

 [ngClass] = "{
    'badge-secondary': somevariable === value1,
    'badge-danger': somevariable  === value1,
    'badge-warning': somevariable  === value1 || somevariable  === value1, 
    'badge-success': somevariable  === value1 }" 

You can use <i [className]="'fa fa-' + data?.icon"> </i>