Skip to content
Advertisement

Laravel Livewire: how to force refresh of a computed property (and the DOM)?

I have a “favorite” component. This component draws a star which gets three classes acording to the state. To select which class to apply to the component, I use a computed property, defined as:

  public function getEsFavoritaProperty() {
    return $this->idea->users()->where('user_id', Auth::user()->id)->count() > 0;
  }

  public function getFavoritaProperty() {

    if (Auth::guest()) return 'voto-idea-inactivo';

    if ($this->EsFavorita) {
      return 'voto-idea-seleccionado';
    } else {
      return 'voto-idea-activo';
    }
  }

It’s Spanish, but I think logic is clear: if there’s no signed user (guest) then function will return voto-idea-inactivo class, if the user is logged on, it will return one or another based in the function that asks if the current item is favorited by the current user.

These two functions works as expected. If I change data in the pivot table directly in the database, the star shows the state correctly.

Now I have this anchor <a> in the star…

<a wire:click.prevent="toggleFavorita">
    <i class="fas fa-star fa-2x {{ $this->favorita }}"></i>
</a>

so it toggles (attach/detach) the relationship, function is:

  public function toggleFavorita() {
    if ($this->EsFavorita) {
      $this->idea->users()->detach(Auth::user()->id);
    } else {
      $this->idea->users()->attach(Auth::user()->id);
    }
  }

This one also works perfectly, if user clicks on the star, the function creates or deletes the relation in the database as it should. The problem is the star doesn’t repaint, and keeps the previous state. If I reload the page, the changes appear.

So how do I force this star to refresh with the new computed value?

Advertisement

Answer

I solved the problem… had nothing to do with refreshing the component ????????‍♂️

Thing is… in the toggleFavorita computed property, I was trying to access another property, in this case EsFavorita defined by getEsFavoritaAttribute()

What I did is to change that function from being a computed property, to a normal function, and then calling that function as so… so modified coded looks now like:

public function EsFavorita() {
    return $this->idea->users()->where('user_id', Auth::user()->id)->count() > 0;
}

public function toggleFavorita() {
    if ($this->EsFavorita()) {
        $this->idea->users()->detach(Auth::user()->id);
    } else {
        $this->idea->users()->attach(Auth::user()->id);
    }
}

I don’t know, looks like a life cycle, that the computed properties refreshes AFTER everything else. I took me a lot of time and lot of Log::info()‘s to figure it out

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement