Add class to element inside *ngFor

I have an item list generated with *ngFor:

<div *ngFor="let item of items"> 
  <div>
     <span>item.description<span>
     <span>item.price</span>
     <button (click)="removeItem(item.id)"> x <button>
  </div>
  ...

The removeItem functions makes a DELETE request to an API endpoint and deletes the item successfully, but the item remains in the view unless I refresh the page.

What I want is to apply a class to set display:none to the deleted item, I have used this:

<div *ngFor="let item of items" [class.dismissed]="itemRemoved">

In the .ts file the itemRemoved is initialized like this:

itemRemoved: boolean = false;

And in the function removeItem is set to true when the API call is successful:

this.http.delete(url)
  .subscribe(
    response => {
      console.log("Item removed");
      this.itemRemoved = true;
    },

But the class is applied to all the items.

How can I apply the class just to the item that I'm removing?

Thanks for your help!

728x90

3 Answers Add class to element inside *ngFor

itemRemoved is a class-wide variable. When you set it to true, its true for everyone. One way you can do it is to have an array of ids that you've removed, and pass a function to the class input that checks to see if the ID is in said array.

(untested, but gist):

export class MyComponent {
  removedItems: any[] = [];

  removeItem(item) {
    this.http.delete(url)
      .subscribe(response => {
        console.log("Item removed");
        this.removedItems.push(item);
      })
  }

  isRemoved(item) {
    return this.removedItems.find(i => item.id === i.id);
  }
}

Template:

<div *ngFor="let item of items" (click)="removeItem(item)" [class.dismissed]="isRemoved(item)">x</div>

Edit:

Or as Juan mentioned in the comments, remove the item from the array you're iterating over. Depends on how items is being populated.

3 months ago

Just assign a isRemoved property to your item so we could distinguish which item was removed. So you need to pass the whole item on the method function then assign the isRemoved property to the item. in the the you then detect with an if statement if the item is removed.

HTML

<div *ngFor="let item of items">
  <div *ngIf="!item.isRemoved">
     <span>item.description</span>
     <span>item.price</span>
     <button (click)="removeItem(item)"> x </button>
  </div>
</div>

Then in your TypeScript

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  items = [
    {
      description: 'sample',
      price: 10
    }
  ];

  public removeItem(item) {
    item.isRemoved = true;
  }
}

3 months ago

You don't need a class to delete that item from the view. The simplest way to do this is remove the item from the array you are iterating. In your example:

  removeItem(item) {
    this.http.delete(url)
      .subscribe(response => {
        console.log("Item removed");
        let index = this.items.indexOf(item);
        this.items.splice(index,1);
      })
  }

I Hope be helpfull.

3 months ago