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.

1 Answer 1

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>
Sign up to request clarification or add additional context in comments.

7 Comments

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.
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 <svg. See stackblitz.com/edit/ng-dynamic-svg
@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.
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...
@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 ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.