M4V3N
M4V3N

Reputation: 629

how to dynamically change conditional [ngClass]

I would like to dynamically assign a class to a specific cell in a table.

<td *ngFor="let col of cols" [ngClass]="col.condition">

An object in "cols" could look like this:

{condition: '{\'prio-high\': priority == 0}', noCondition: 'prio-high'}

I made sure that priority is indeed == 0.

Is this even possible? The following example works just fine. It just doesn't seem to work if I want to work with conditions.

<td *ngFor="let col of cols" [ngClass]="col.noCondition">

Example:

.html

<style>
  .condition{background-color: red}
  .noCondition{background-color: blue}
  .someRandomOtherCondition{background-color: orange}
</style>

<div *ngFor="let o of objects" [ngClass]="o.template">
  {{ o.name }} has priority {{ o.prio }}
</div>  

.ts

export class AppComponent  {

  info = [
      {object1: 'noCondition'},
      {object2: '{\'condition\': prio == 0}'}
    ]

  objects = [
    {
      name: 'object1',
      prio: 0, //imagine this number is being dynamically assigned and we don't know the value beforehand
      template: 'noCondition'
    },
    {
      name: 'object3',
      prio: 0, //imagine this number is being dynamically assigned and we don't know the value beforehand
      template: 'someRandomOtherCondition'
    },
    {
      name: 'object2',
      prio: 1, //imagine this number is being dynamically assigned and we don't know the value beforehand
      template: '{\'condition\': prio == 1}'
    }
  ];

}

if you run this example you will see that object2 is never being formatted properly as it should.

stackblitz: https://stackblitz.com/edit/angular-dani1p

Upvotes: 1

Views: 1483

Answers (2)

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24462

You can test different cases with the same variable something like this

component

  state : number=0;

  ngOnInit() {
    setInterval( () => {
      this.state = Math.floor(Math.random() * 15)
    },2000)
  }

template

<p [ngClass] ="{red: state < 5,green : state >=5 && state <=7 , blue : state > 7 }">
  O.o => {{state}}  something magical happen :)
</p>

Demo 🚀🚀

so for you case you can update the ngClass to something like this

<ul>

  <li *ngFor="let col of cols" 
    [ngClass]="{red:col.priority == 0,green: col.priority == 1,blue:  col.priority==3}">
            {{col.name}} priority => {{col.priority}}
        </li>
    </ul>

Demo 🌟🌟

UPDATED!💣👻

we need to evaluate the string condition where the condition include a property of the object like a variable , this remind me to [with][3] statement so far you can't use with statement but I mange to get the same result by using the Function constructor and object destructor and the result look like this ⬇

  public getCondition(obj, condition) {
    const props = Object.keys(obj).reduce( (acc, next) => `${acc} , ${next}`);
    const evalCon = new Function(` return function ({${props}})  { return ${condition}} `);
    return evalCon()(obj)
  }

template

<ul>
    <li *ngFor="let obj of objects" [ngClass]="getCondition(obj,obj.template)" >
        {{obj.name}} 
    </li>
</ul>

Demo 🔥🔥

Upvotes: 1

Jacopo Sciampi
Jacopo Sciampi

Reputation: 3443

NgClass can be used with an if statement to assign dinamically classes.

Here's an example if you want to assign the class "prio-high" when the condition col.noCondition is equal to 0 :

<td *ngFor="let col of cols" [ngClass]="{'prio-hight' : col.noCondition == 0}">

Upvotes: 0

Related Questions