Search code examples
htmlcssangularshow-hide

*ngIf doesn't delete the element when False, creates new one when True


I am just starting with Angular and have a problem with *ngIf

When the app starts, *ngIf="item.done" correctly displays (or not displays) the element based on whether the ToDo item is done. However, when I click on the element, the done state changes (I am console.logging it), but the element doesn't disappear, whatever the state. Instead, when the state goes back to done, it creates the same element again.

My HTML template

The onTick() function that changes the item.done state

  1. item.done = false Hidden Screenshot
  2. 1st click –> item.done = true Shown
  3. 2nd click –> item.done = false Shown
  4. 3rd click –> item.done = true Shown TWICE Screenshot

// MOCK DATA

import { Item } from './item';

export const ITEMS: Item[] = [
  {id: 1, title: 'Buy Milk', done: false},
  {id: 2, title: 'Do Math', done: true},
  {id: 3, title: 'Cook food', done: false}
]



// THE COMPONENT TypeScript

import { Component, OnInit } from '@angular/core';
import { ITEMS } from './mock-items';
import { Item } from './item';

@Component({
  selector: 'app-list',
  templateUrl: './list.component.html',
  styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {
  items: Item[] = [];

  constructor() {
    this.items = ITEMS
  }

  ngOnInit() {
  }

  onTick(item) {
    console.log('Item was: ', item.done)
    item.done = !item.done
    console.log('Item became: ', item.done)

  }

}
<!-- THE COMPONENT HTML -->
<div class="list">
  <div class="list--header">
    <h1>List</h1>
  </div>

  <div class="list--content">
    <ul class="list--items">
      <li *ngFor="let item of items">
        <div class="checkbox" (click)="onTick(item)">
          <input type="checkbox" style="display: none">
          <i *ngIf="item.done" class="tick fas fa-check"></i>
        </div>
        {{item.title}}
      </li>
    </ul>
  </div>

  <div class="list--footer">

  </div>
</div>


Solution

  • EDIT

    The problem happens when Font Awesome's SVG, instead of appearing as a child of the <i *ngIf="item.done" class="tick fas fa-check"></i>, replaces the element, and so the *ngIf attribute disappears. Looks like we shouldn't ever use Angular attributes on an element with Font Awesome classes (target the parent element, instead).

    How it Used to Be (Doesn't work)

    <i *ngIf="item.done" class="tick fas fa-check"></i>
    

    Solution

    <div *ngIf="item.done">
       <i class="tick fas fa-check"></i>
    </div>