3

I'm working on an Angular project where I need to have one class or another depending on a variable (and they have to change live, without refreshing).

I tried using *ngIf/else and [ngClass]and they do work but they do not re-render. They only work when I refresh the website

Using *ngIf/else:

<i
 *ngIf="favSongs.includes(track.id); else plus"
 (click)="setToFav(track.id)"
 class="fa fa-check"
></i>
<ng-template #plus>
  <i (click)="setToFav(track.id)" class="fa fa-plus"></i>
</ng-template>

Using [ngClass]:

<i
  (click)="setToFav(track.id)"
  [ngClass]="{'fa fa-check': favSongs.includes(track.id), 
  'fa fa-plus': !favSongs.includes(track.id)}"
></i>

As said before, it does work but only when you refresh. I'm looking for something like React, when you update the class the component get re-rendered.

Sourav Dutta
  • 1,267
  • 1
  • 19
  • 25
Mr. Moretto
  • 41
  • 1
  • 4
  • What does `setToFav` do? Because the behaviour you want is how Angular works, so there is something else wrong with your code. There is no need to refresh a page for this to work. Have you changed the changedetection strategy? – Daniel B Apr 28 '19 at 14:57
  • This is what it does http://prntscr.com/nhx9u5 – Mr. Moretto Apr 28 '19 at 15:06
  • 1
    You never modify the actual `favSongs` array, but instead local storage. Your component doesn't know how to listen to local storage, so that's why it doesn't work. The answer provided to this questions makes a suggestion to reassign the array to a new value where you've pushed the new favorite song, which should work just fine! – Daniel B Apr 28 '19 at 15:08

2 Answers2

4

Change detection only fires when the value of a binding has changed. The value for primitives is their value, and for objects its the value of their reference.

Adding a track to an array of tracks will mutate the binded object, but not change its reference, and not trigger change detection.

This is one reason for using immutable objects.

In setToFav you could do faveSongs = faveSongs.push(track.id).slice(); or so.

0

In your component, favSongs never gets updated: it gets value assigned in the ngOnInit (so, once in the lifetime of the component), and that's it. setToFav only manipulates local storage (favSongs doesn't automatically get updated, you have to to it explicitly).

mbojko
  • 13,503
  • 1
  • 16
  • 26