Array in NgClass with method call and variable
Asked Answered
H

2

8

I want to use [ngClass] with a method call that returns an object like {currentWeek: true} and I want to add the var week.state that can have the value rejected.

I want that the HTML looks like this: <div class="currentWeek rejected"></div> but when I use it I get this error:

Error in ./FlexCalendar class FlexCalendar - inline template:29:13 caused by: NgClass can only toggle CSS classes expressed as strings, got [object Object]

How can I combine a method call and a variable into the ngClass? Something like [ngClass]=[setWeekClasses(week), week.state]

setWeekClasses(week: Week): Object {
    let state: string = this.state(week.state);
    return {
        'currentWeek': week.weekNumber === this.selectedDate.getWeekNumber(),
        [week.state]: true,
    };
}
Hadlee answered 9/1, 2017 at 11:9 Comment(3)
Can you add your method where you return the object?Satyr
@echonax Added ;)Hadlee
Just correct it to [ngClass]=setWeekClasses(week) that's itContrarily
F
3

You can use a method and a variable to construct the classes-string for the ngClass.

For example see here a class providing a method and a object variable providing class information:

class { 

   getCSSClass() {
     return  { state: "rejected" }
   }

 week:object = {
    state: 'rejected'
  }
}

In Template then you can use a method and a variable to construct the classes-string for the ngClass.

   <div [ngClass]="getCSSClass().state + ' currentWeek'">">
      <h2>Hello {{name}}</h2>
   </div>

or you can write:

@Component({
  selector: 'my-app',
  template: `
    <div [ngClass]="week.state + ' ' + getCSSClass().state">
      <h2>Hello {{name}}</h2>
    </div>
  `,
})

Check here in plunker: http://plnkr.co/edit/JfN5cjbCjNAUs8qx9oh1

Fogdog answered 9/1, 2017 at 11:19 Comment(5)
Why can i not write something like [ngClass]=[week.state, getWeekState(week)]Hadlee
I updated answer and plunker; I guess what you want to write is not supported by ngClass grammar. angular.io/docs/ts/latest/api/common/index/…Fogdog
I added new code explaining to my question. But I think it is not possible with ngClass to combine a method call and a variableHadlee
I did in plunker. Check it thereFogdog
If you do some tracing, you'll find that this pattern causes repeated / infinite digest loops, as Angular appears to be unsure that the returned value of the function...Fletafletch
E
7

Binding to a method or function is discouraged and returning a new object instance is especially bad.

You should at least cache the result

oldWeek;
oldStyles;
setWeekClasses(week: Week): Object {
    if(this.oldWeek != week) {
      let state: string = this.state(week.state);
      this.oldStyles = {
        'currentWeek': week.weekNumber === this.selectedDate.getWeekNumber(),
        [week.state]: true,
      };
      this.oldWeek = week;
    }

    return this.oldStyles;
}

then you can use it like

[ngClass]="setWeekClasses(week)"

This binding

[ngClass]=[week.state, getWeekState(week)]

is invalid because ngClass supports a string, a list of strings and an object with string values while [week.state, getWeekState(week)] results in a list that contains a string and an object, which is not supported.

Eddington answered 9/1, 2017 at 12:10 Comment(1)
Great explanation. Thanks. Even having an undefined in the array will result in error rendering.Bladdernose
F
3

You can use a method and a variable to construct the classes-string for the ngClass.

For example see here a class providing a method and a object variable providing class information:

class { 

   getCSSClass() {
     return  { state: "rejected" }
   }

 week:object = {
    state: 'rejected'
  }
}

In Template then you can use a method and a variable to construct the classes-string for the ngClass.

   <div [ngClass]="getCSSClass().state + ' currentWeek'">">
      <h2>Hello {{name}}</h2>
   </div>

or you can write:

@Component({
  selector: 'my-app',
  template: `
    <div [ngClass]="week.state + ' ' + getCSSClass().state">
      <h2>Hello {{name}}</h2>
    </div>
  `,
})

Check here in plunker: http://plnkr.co/edit/JfN5cjbCjNAUs8qx9oh1

Fogdog answered 9/1, 2017 at 11:19 Comment(5)
Why can i not write something like [ngClass]=[week.state, getWeekState(week)]Hadlee
I updated answer and plunker; I guess what you want to write is not supported by ngClass grammar. angular.io/docs/ts/latest/api/common/index/…Fogdog
I added new code explaining to my question. But I think it is not possible with ngClass to combine a method call and a variableHadlee
I did in plunker. Check it thereFogdog
If you do some tracing, you'll find that this pattern causes repeated / infinite digest loops, as Angular appears to be unsure that the returned value of the function...Fletafletch

© 2022 - 2024 — McMap. All rights reserved.