3

I'm using a video series to get familiar with Angular, codewithmosh. He uses glyphicons in one of his exercises, but the video's from 2018. Glyphicon support seems to have been discontinued in bootstrap since then, but the bootstrap site still includes the html for their icons. I figured I would see if I could just do the same thing by pushing around raw html.

Problem is, the html pulled from component.ts is not rendering, and instead just shows the html code on the page. That same html in the component.html IS rendering.

I'm really new here so there could be an obvious flaw in my code. It's probably not pretty but it SEEMS sound, and I can't figure out why it's not working. Ideally this should be rendered as an empty star, which when clicked switches to the full star.

Thanks in advance for any help!

here's the app.component.ts:

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

@Component({
  selector: 'app-star',
  templateUrl: './star.component.html',
  
 })

export class StarComponent {
  isClicked: boolean;

  
  fullStar: string = `
  <svg (click)="onClick()" width="2em" height="2em" viewBox="0 0 16 16" class="bi bi-star-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
    <path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
  </svg>
  `;

  emptyStar: string = `
  <svg (click)="onClick()" width="2em" height="2em" viewBox="0 0 16 16" class="bi bi-star-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
    <path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
  </svg>
  `;

  currentSymbol: string = this.emptyStar;
  
  onClick() {
    this.isClicked = !this.isClicked;

    this.currentSymbol = this.isClicked ? this.fullStar : this.emptyStar;
    
  }
}

Here's the star.component.html:

{{currentSymbol}}
-------
    <svg (click)="onClick()" width="2em" height="2em" viewBox="0 0 16 16" class="bi bi-star-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
        <path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
    </svg>

Here's the app.component.html, super basic:

<app-star></app-star>

And here is the html output. And here is the html output.

Matt S
  • 249
  • 2
  • 8

1 Answers1

2

Both svgs you provided are filled, but I made you an example using a normal star and a small star.

Just replace the small star with an empty star, and it will do the trick.
what I basically did is, I put an ngIf on both svgs, one with the condition isClicked and the other with the opposite of the condition, so !isClicked.
you function for changing the condition onClick() is working just fine.

Edit: (with more explanation)

To make your typescript simple you just need isClicked property and onClick function:

export class AppComponent {
  isClicked: boolean;

  onClick() {
    this.isClicked = !this.isClicked;
  }
}

and in you template you can add the two svgs you want to switch between, with an ngIf on each one of them:

<!-- big star -->
<svg *ngIf="isClicked" (click)="onClick()" width="2em" height="2em" viewBox="0 0 16 16" class="bi bi-star-fill" fill="currentColor"
    xmlns="http://www.w3.org/2000/svg">
    <path
        d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" />
</svg>

<!-- small star -->
<svg *ngIf="!isClicked" (click)="onClick()" width="2em" height="2em" viewBox="0 0 16 24" class="bi bi-star-fill" fill="currentColor"
    xmlns="http://www.w3.org/2000/svg">
    <path
        d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.283.95l-3.523 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" />
</svg>
Elmehdi
  • 1,390
  • 2
  • 11
  • 25
  • 1
    This is probably the best answer, I will upvote it once you post the code here, we tend to avoid links without the relevant code in the answer. – Ruan Mendes Oct 07 '20 at 20:12
  • 1
    Note that you don't need two separate `svg` elements in your HTML, I changed your example to be `[attr.viewBox]="'0 0 16 ' + (isClicked ? 24 : 16)"` using just a single ` – Ruan Mendes Oct 07 '20 at 20:18
  • @JuanMendes I did add my code for the answer to be relevant even without the link. but I kept the two svgs separated just to make it easy to change to two completely different svgs if needed. – Elmehdi Oct 07 '20 at 20:31
  • 1
    I guess that's OK, but you're answering this question which doesn't need two SVGs. It would be a better answer if you made it as concise as possible instead of worrying about what it could be... – Ruan Mendes Oct 07 '20 at 20:43
  • @JuanMendes maybe I didn't understand the question well, didn't the poster of the question say he wants to switch back and forth between two svgs ? – Elmehdi Oct 07 '20 at 20:48
  • This answer worked beautifully, thank you! It looks like it was caused by me just not being familiar with the implementation of ngIf and the HTML. Like I said I'm fairly new at it. I did need a second svg, but that was actually my mistake in having the same code instead of different ones. Was an easy fix. Thanks again! – Matt S Oct 07 '20 at 21:24
  • Out of curiosity though, what in my original code kept the HTML from rendering as it was? I want to make sure I can keep from making that mistake again. – Matt S Oct 07 '20 at 21:25