manish sharma
manish sharma

Reputation: 47

Assign a class to a div inside *ngFor based on condition

I need to assign a class to a div that is inside a *ngFor iteration, based on a method.

Below is my HTML code: -

<ng-container *ngFor="let data of totalData let j = index">
          <div>
            <a (click)="selectData(data)">
              <div [ngClass]="{selected : selectedCodeMethod(data)}">
                {{data.code}}
              </div>
            </a>
          </div>
        </ng-container>

My Ts code:-

selectedCodeMethod(data){
   if(this.selectedCode.includes(data.code)){
             return true;
     }
             return false;
}

selectData(data){
    this.selectedCode.push(data.code);
}

Even if the selectedCodeMethod() changes the content of selectedCode array, the method inside ngClass doesn't reflect changes.

What changes do I need to make?

Upvotes: 0

Views: 684

Answers (1)

Tal Ohana
Tal Ohana

Reputation: 1138

Calling function in Angular template is discouraged since it is inefficient and can raise errors - more about it in this article.

Back to your question, you should create Angular Pipe to match your needs. In your scenario we need a pipe that accepts an array and an element and return array.includes(element);:

@Pipe({
  name: "includes"
})
export class IncludesPipe implements PipeTransform {
  transform<T>(array: T[], element: T): boolean {
    return array.includes(element);
  }
}

Next, in your component you need to use the pipe and pass additional arguments

@Component({
  selector: "app-root",
  template: `
    <ul>
      <li
        *ngFor="let item of items"
        [ngClass]="{ selected: selectedItems | includes: item }"
      >
        Item {{ item }}
      </li>
    </ul>
  `,
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  items = [1, 2, 3, 4, 5];
  selectedItems = [1, 3];
}

Lastly, pipes are pure, meaning you need to make immutable updates:

selectData(data){
    this.selectedCode = [ ...this.selectedCode, data.code ];
}

You can experiment with the code in this Code Sandbox

Upvotes: 1

Related Questions