4

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?

5
  • Thanks. How should I call the function?. I placed $this->render() just after updating the databse (in the toggleFavorita() function), but it doesn't work Commented Oct 8, 2020 at 4:02
  • Uhmmm it's strange, I have to click twice, and of course it shows the PREVIOUS state. I mean, its "off", I click... stays off. I check in the database and there's the relation, I click again, it goes "on" but the database doesn't have the relation anymore???? Commented Oct 8, 2020 at 4:06
  • That gave me an error: "Public method [toggleFavorita;$refresh] not found on component: [show-idea]" Commented Oct 8, 2020 at 4:07
  • $this->render(); it should work Commented Oct 8, 2020 at 4:11
  • Nah... I tried it also doens't work. I placed the $refresh on a standalone button, and it works, but its a bit dumb to click on the star and then in the other button. I called toggleFavorita(); $refresh on the button, but it doesn't work either Commented Oct 8, 2020 at 4:16

2 Answers 2

4

In case someone does need to force a refresh of a computed property in Livewire, you can do it using the forgetComputed method.

// forget all computed properties
$this->forgetComputed();

You can also pass one or more property keys to this method to reset specific properties.

Source: https://github.com/livewire/livewire/blob/master/src/Component.php

Sign up to request clarification or add additional context in comments.

2 Comments

amazing, super helpful and works for me. you can forget a specific property by doing $this->forgetComputed('jobs')
Livewire v3 advises to use the PHP's unset() method instead. livewire.laravel.com/docs/computed-properties#busting-the-cache
3

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

Comments

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.