Solution 1 :

Resolution

Wasted lot of my free time to investigate how to resolve this issue. Tried everything with Renderer2 and all dirty Javascript methods. But one day I came up with idea to use innerHtml.

Rendering new string of inner HTML changes Font Awesome icons interactively.

category-dialog.component.html

<div [ngStyle]="selectedColor" [innerHtml]="selectedIconHtml"></div>

category-dialog.component.ts

openIconDialog(): void {
  const dialogRef = this.dialog.open(DialogIconSelectComponent, { width: '15rem' });
  dialogRef.afterClosed().subscribe((result: string) => {
    // EVERY TIME NEW ELEMENT WITH NEW FA CLASS
    this.selectedIconHtml = `<i class="${result}"></i>`;
  });
}

This solution – on every icon selection’s changing <div> element content (inner html).

Solution 2 :

I solved this issue like this:

<div innerHTML="<i class='{{icon}}'></i>">
</div>

In this case, icon will be rerendered after value changes. innerHTML makes this happen easily. No need any code in TS file.

Problem :

Is there any way to change font awesome icon dynamically? I want user to be able to select one of font awesome icons dynamically. It works only when you add class first time. The place where I try to do it is – MatDialog. There is form where user have to select icon, background color and category name. To select icon user should open another dialog.

enter image description here enter image description here

I’m using Angular 9.1.4 and Font Awesome 5.13.0.


That’s what I tried:

1. Using ngClass

category-dialog.component.html

<div [ngStyle]="selectedColor">
    <i [ngClass]="selectedIcon"></i>
</div>

category-dialog.component.ts

openIconDialog(): void {
  const dialogRef = this.dialog.open(DialogIconSelectComponent, { width: '15rem' });
  dialogRef.afterClosed().subscribe(result => {
    this.selectedIcon = result;
  });
}

This works only first time. But when you try to change icon selectedIcon changes, but UI doesn’t refresh element class.


2. Using @ViewChild

@ViewChild('iconElement') iconElement: ElementRef;

constructor(private dialog: MatDialog,
            private renderer: Renderer2) { }

openIconDialog(): void {
  const dialogRef = this.dialog.open(DialogIconSelectComponent, { width: '15rem' });
  dialogRef.afterClosed().subscribe((result: string) => {
    this.iconElement.nativeElement.className = result;
  });
}

This also works only first time.


3. Using @ViewChild and Renderer2

category-dialog.component.html

<div #colorElement [ngStyle]="selectedColor">
    <i #iconElement></i>
</div>

category-dialog.component.ts

@ViewChild('colorElement') parentElement: ElementRef;
@ViewChild('iconElement') childElement: ElementRef;

constructor(private dialog: MatDialog,
            private renderer: Renderer2) { }

openIconDialog(): void {
  const dialogRef = this.dialog.open(DialogIconSelectComponent, { width: '15rem' });
  dialogRef.afterClosed().subscribe(result => {
    this.replaceIcon(result);
  });
}

replaceIcon(iconClass: string): void {
  const i = this.renderer.createElement('i');
  this.renderer.setProperty(i, 'class', iconClass);
  this.renderer.removeChild(this.parentElement.nativeElement, this.childElement);
  this.renderer.appendChild(this.parentElement.nativeElement, i);
}

That doesn’t work at all.


Is there any way how to change font awesome dynamically?

Comments

Comment posted by Wahab Shah

can you setup a stackblitz with minimum functionality?

Comment posted by geeksforgeeks.org/…

geeksforgeeks.org/…

Comment posted by Dumbo

@Frost Whats is similar between HTML element style and

Comment posted by Dumbo

@WahabShah I guess it’s enough information here

Comment posted by Dumbo

@mplungjan You’re totally wrong here, because as you see I tried common methods for angular, but that doesn’t work for

By