0
votes

So I'm looping over a list of items in my html and setting a calling a function to return true or false so that I can apply respective classes, also I'm setting a variable if any of the item gets matched in the list. I'm using this variable for another element as *ngIf. Now initially, before the template loads, this variable is false. After that the component initializes and the html renders. Now where I have a looping of list of items I'm calling a function over there, it is setting that variable as true but the element that is conditioned with ngIf is not getting visible.

I think it's because when the component is fully initialized the variable value is false and then when the html renders the variable's value is changed to true. But this change is not detected by angular as it has already rendered that element and also didn't get any change event to watch for the variables.

Here is my html

<div *ngIf="someVariable">
some content
</div>

<div *ngFor="let item of items">
  <div [ngClass]="{isItemMatched(item) : my-class}"></div>
</div>

Here is my component

somevariable = false

isItemMatched(item) {
  forLoop() {
   if(true) {
      this.someVariable = true
      return true
     }
   }
}

Is there any way to so that we can trigger angular change detection like in a click event or soemthing so that angular can update the view?

1
Calling functions from view bindings (except of course event handlers) is very bad practice and in almost all cases is not what you want. Prepare an array with the data and the precalculated isItemMatched result for each item and bind to this array in the view. - Günter Zöchbauer
You're getting this all wrong. in Angular, you don't iterate the HTML. You iterate the data that generates the HTML. Alter your data, then in the *ngFor loop, add a condition whether an element must be rendered or not, based on the data you iterate. - Jeremy Thille
Thanks guys, yea I also thought it's a bad practice - Manzur Khan

1 Answers

1
votes

First of all, you are using ngClass in wrong way. The left side of ngClass should be the class name and right side should be boolean value. Eg.

<div [ngClass]="{'my-class' : isItemMatched(item)}"></div>

To update the view when value changes, you can use ChangeDetectorRef Inject this class in your constructor and then use the method markForCheck(). This method updates the view.

constructor(private cdr: ChangeDetectorRef){
}
someMethod(){
  this.someVariable = true; //Value changed.
  this.cdr.markForCheck(); //View updated.
}