*ngIf doesn't actually remove the element if the condition is False; rather, it generates a new one when the condition

As I venture into the world of Angular, I encountered a snag with *ngIf

Upon launching the app, *ngIf="item.done" works correctly in showing or hiding the element based on whether the ToDo item is marked as done. However, upon clicking on the element, despite the change in the done state (confirmed by console logging), the element does not vanish. Instead, regardless of the state change, if it goes back to being done, the same element is created once more.

Here's my HTML template

Check out the onTick() function, responsible for toggling the item.done state

  1. item.done = falseHidden Screenshot
  2. 1st click → item.done = trueShown
  3. 2nd click → item.done = falseShown
  4. 3rd click → item.done = trueShown 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>

Answer №1

UPDATE

An issue arises when Font Awesome's SVG replaces the

<i *ngIf="item.done" class="tick fas fa-check"></i>
element instead of being a child, causing the *ngIf attribute to disappear. It seems best practice to avoid using Angular attributes on elements with Font Awesome classes (target the parent element instead).

Previous Structure (Not Functional)

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

Solution

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

Answer №2

Consider enclosing the icon in a DIV tag... Additionally, it's worth noting that ngIf is not meant to simply "hide" elements but rather add or remove them from the DOM. If you're looking to toggle visibility, you might want to explore ngHide instead.

I trust this information proves useful to you.

Answer №3

Here's another suggested solution to consider:

To prevent HTML from getting messed up, you can configure the FontAwesomeConfig property autoReplaceSvg to nest. This will automatically nest the SVG inside the <i> element.

<script>
  // Include this in your index.html or similar file
  FontAwesomeConfig = { autoReplaceSvg: 'nest' }
</script>

After setting it up, you can use it as usual.

<i class="my-icon fas fa-coffee" data-fa-mask="fas fa-circle"></i>

You will see the following result after implementation:

<i class="my-icon" data-fa-mask="fas fa-circle" data-fa-processed="">
  <svg class="svg-inline--fa fa-coffee fa-w-16" data-fa-mask="fas fa-circle" aria-hidden="true" data-fa-processed="" data-prefix="fas" data-icon="coffee" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">...</svg>
</i>

For more details, refer to the official documentation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Pagination CSS may fail to function properly in Chrome after an AJAX call is returned

Having an issue with CSS not getting applied correctly after making an AJAX call with pagination. The problem seems to be specific to Chrome, as it works fine in Firefox. When inspecting the element, the CSS is present but not being applied properly until ...

What is causing setTimeout to not function as intended?

I'm having some trouble moving a <div id="box"> whenever my mouse hovers over it. Currently, the element only moves when I trigger the mouseover event on the div itself instead of when my mouse is actually hovering over it. document.getElements ...

Experiencing problem when using Angular Dart material-input with data type set to number

I am currently in the process of constructing a web application (essentially an e-commerce platform) using Angular Dart and incorporating elements from materialDirectives to create the app's components. My primary focus at the moment is on developing ...

How to troubleshoot a click event not being stopped in Angular 2

Despite using HostListener on a click event to prevent event propagation, the click handler on the actual element still activates. Below is the pertinent code and a stackblitz demonstration for reference. // Custom Directive @Directive({ selector: &apo ...

Ways to enhance a website by adding a custom calculated column

I'm feeling a bit lost and in need of some technology advice. What is it that I truly desire? Picture this scenario: You land on a website and come across a table/div setup that looks something like this: <div class="a"> <div class="pri ...

Manipulating the zoom level of a webpage through HTML tags or javascript

Is there a way to adjust the zoom level of a webpage using HTML or JavaScript? I am trying to display a webpage on Internet explorer 9 with a zoom property set to 85%. ...

JavaScript code for transitioning between a thumbnail and a full-width image header on a webpage

I am looking to create transitions in NextJs that involve a smooth shift from a thumbnail image to a full-screen header when clicking on a project from the home page. I prefer utilizing internal routing rather than React Router, but I am open to using that ...

I created a design for a subscription form that appears aesthetically pleasing in Firefox, however, it does not maintain the same appearance in Opera. Any suggestions on how I can resolve this issue?

Why does my code display differently in Firefox compared to Opera? In Firefox, the height of input/text and input/submit elements are similar. However, in Opera, the height of the input/submit is reduced. This is the HTML code: < ...

Angular Tutorial: Modifying the CSS transform property of HTML elements within a component directly

Currently, I'm in the process of developing an analog clock for a project using Angular. My challenge is figuring out how to dynamically update the sec/min/hour handlers on the clock based on the current time by manipulating the style.transform prope ...

The submit button seems to be unresponsive or unreactive

As a newcomer to Angular 2 and Typescript, I am in the process of building a web application. I have created several input fields and, following user submission via a button, I want to log the inputs to the console. However, it seems like my button is not ...

In Angular 5, you cannot assign type 'any[]' to type 'typeof User'

After extracting data from the JSON file, I encountered a typo error message stating: Type 'any[]' is not assignable to type 'typeof User'. Here is my code in app.component.ts: import { Component, OnInit } from '@angular/core&a ...

What is the process for resetting a JQueryUI effect animation?

I'm facing an issue with two timer bars that each wind down over a 5-second period. When I try to stop and reset the first timer, it simply continues from where it left off instead of resetting. The desired behavior is as follows: Timer1 starts User ...

Importing $sce in Angular 5: A Step-by-Step Guide

Exploring the concept of $sce or Strict Contextual Escaping, to allow trusted HTML explicitly. Attempting to utilize DOMSanitizer for sanitizing the String, but encountering issues. **format-xml.pipe.ts** import { Pipe, PipeTransform } from '@angul ...

How to Perfectly Position Content with Bootstrap 3's Full Width Image Carousel

Here's my query: Is there a way to adjust the position of my content (such as text) inside the slider responsively? The text can be positioned anywhere within the Div Slider, for example, at 25% from the left and 50% from the top within the Image Di ...

Navigating Through the DOM with Selenium using XPath Axes

Currently, I am developing Selenium tests for a dynamic web page. Within this section of code, I am extracting data from an Excel sheet and verifying if a specific element exists on the webpage. I have annotated the critical part of the code with comments ...

Receiving JSON information from a web address using Javascript

I'm currently faced with a challenge in extracting JSON data from a web server. Despite the absence of errors in my code, I encounter difficulties displaying any output. Below is a snippet of the issue: <!DOCTYPE HTML> <html> <head ...

What is the best way to inject child nodes into parent nodes without causing the view to shift to the location where the element is being

While I am rendering elements and appending them to a parent div, my screen keeps jumping to the bottom-most element as it loads instead of maintaining the current view. Ideally, it should start at the top of the screen and remain there without any sudden ...

Use Bootstrap to effortlessly arrange columns horizontally in a row

I'm facing a scenario where I need to arrange the columns in a row horizontally. The challenge is to ensure that the row expands horizontally to fit the columns. I attempted to use white-space: nowrap on the row, remove floats on columns, and set the ...

ESLint is unable to locate the OnInit function within the "@angular/core" module

There seems to be an error: import { Component, OnInit, Input, ViewChild, ElementRef } from "@angular/core"; OnInit not found in '@angular/core'eslintimport/named The code appears to be functioning correctly, so perhaps there is a m ...

The issue with Angular 5 Interceptor failing to log out upon a server call error

Source : https://gist.github.com/tobbbe/08e01db92c32346b226333a3f952df22 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(this.addToken(request)) .pipe( ...