Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic classname inside ngClass in angular 2

Tags:

angular

People also ask

Can you have class and ngClass together?

yes , you can do it. Did you try it? What happened? You can use both class and ngClass as the first one gives you the opportunity to apply a class that you want to implement in all cases under any circumstances and the later to apply classes conditionally.

What is the difference between ngClass and class?

ngClass is more powerful. It allows you to bind a string of classes, an array of strings, or an object like in your example. The above two lines of code is with respect to CSS class binding in Angular. There are basically 2-3 ways you can bind css class to angular components.


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

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.


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

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.