Dynamic classname inside ngClass in angular 2

  <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>

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.


Try

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

instead.

or

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

or even

<button class="{{type === 'mybutton' ? namespace + '-mybutton' : ''}}"></button>

will work but extra benefit of using ngClass is that it does not overwrite other classes that are added by any other method( eg: [class.xyz] directive or class attribute, etc.) as class does.

Angular 9 Update

The new compiler, Ivy, brings more clarity and predictability to what happens when there are different types of class-bindings on the same element. Read More about it here.


ngClass takes three types of input

  • Object: each key corresponds to a CSS class name, you can't have dynamic keys, because key 'key' "key" are all same, and [key] is not supported AFAIK.
  • Array: can only contain list of classes, no conditions, although ternary operator works
  • String/ expression: just like normal class attribute

Tags:

Angular