0

I realise this might be a duplicate of this or this, but i've gotten blind to this. Im getting my data from a rest api as an object, which contains number of votes. The toggle function works on all the fontawesome icons, and not just the specific ones, even though the counters are working fine. I want the filled heart icon to be toggled on the specific story, when the icon has been pressed. Vice versa when it's been pressed again.

I'm using angular4 and fontawesome 5.

The data is from an observable in my service.

Component:

private vote(story) {
    this.liked = !this.liked; //heart filled
    if (story.userVote == false) {
      this.storiesService.voteStory(story.objectID)
        .subscribe(
        (data) => {
          console.log("Added upvote")
          story.votes++;            //api counter
          console.log(story.votes)
          story.userVote = true;    //api call
        })
    } else if (story.userVote == true) {
      this.storiesService.unVoteStory(story.objectID)
        .subscribe(
        (data) => {
          console.log("Removed upvote")
          story.votes--;
          console.log(story.votes)
          story.userVote = false;
        })
    }
  }

HTML:

  <a (click)="vote(story)" style="font-size: 13px;" *ngIf="!liked" matTooltip="Like story" matTooltipPosition="above"><i class="far fa-heart"></i> {{ story.votes || 0 }} </a>
  <a (click)="vote(story)" style="font-size: 13px;" *ngIf="liked" matTooltip="Like story" matTooltipPosition="above"><i class="fas fa-heart"></i> {{ story.votes || 0 }} </a>
blixenkrone
  • 388
  • 2
  • 7
  • 20

3 Answers3

2

this.liked refers to the liked property in the component. You'll have to toggle/store a liked property for every separate story. Otherwise, toggling this.liked to true/false will set the property for the whole component, therefore it will be true/false for every *ngIf at the same time.

What you need to do is something along the lines of this:

<a (click)="vote(story)" style="font-size: 13px;" *ngIf="!story.liked" matTooltip="Like story" matTooltipPosition="above"><i class="far fa-heart"></i> {{ story.votes || 0 }} </a>
<a (click)="vote(story)" style="font-size: 13px;" *ngIf="story.liked" matTooltip="Like story" matTooltipPosition="above"><i class="fas fa-heart"></i> {{ story.votes || 0 }} </a>

And toggle it like so:

private vote(story) {
    story.liked = !story.liked;
    //Cut for brevity
  }
DGarvanski
  • 2,555
  • 3
  • 26
  • 35
1

Why don't you use ngClass (and only one icon tag) instead of this ngIf to toggle the fas/far class?

<i ngClass="{'fa-heart': true, 'far': !liked, 'fas': liked }">
Christian Benseler
  • 7,907
  • 8
  • 40
  • 71
  • +1 for making the obvious suggestion although it doesn't actually answer their question, they probably still need to use `story.liked` as suggested above. – Duncan Oct 19 '17 at 13:51
0

So i used the userVote boolean in my api, and ended up like this:

Component:

private vote(story) {
    if (story.userVote == false) {
      story.userVote = !story.userVote; //heart filled
      ....
}

HTML:

<a (click)="vote(story)" style="font-size: 13px;" *ngIf="story.userVote===false" matTooltip="Like story" matTooltipPosition="above"><i class="far fa-heart"></i> {{ story.votes || 0 }} </a>
<a (click)="vote(story)" style="font-size: 13px;" *ngIf="story.userVote" matTooltip="Like story" matTooltipPosition="above"><i class="fas fa-heart"></i> {{ story.votes || 0 }} </a>
blixenkrone
  • 388
  • 2
  • 7
  • 20