Search code examples
phplaravellaravel-livewire

Can't refresh a Livewire component after wire:click button


I can't seem to get my LikeCounter livewire component to be able to refresh after i clicked a button that triggers a wire:click event.

My LikeCounter Livewire component:

class LikeCounter extends Component
{
    public $id,$photo,$like_count,$like_exist;

    protected $listeners = [
        'refreshParent' => '$refresh',
      ];
      
    public function mount($id)
    {
        $this->id = $id;
        $this->photo = Photo::find($this->id);
        $this->like_count = LikeCount::count();
        if(LikeCount::where('user_id',Auth::id())->where('photo_id',$this->id)->get()->isEmpty() == false ){
            $this->like_exist = 1;
        }
        else{
            $this->like_exist = 0;
        }
    }
    public function like()
    {
        $this->photo = Photo::find($this->id);
        $user_id = Auth::id();
        $this->photo->likes()->create([
            'user_id' => $user_id,
            'photo_id'=> $this->photo->photo_id
        ]);
        $this->dispatch('refreshParent');
    }
    public function unlike()
    {
        $this->photo = Photo::find($this->id);
        $user_id = Auth::id();
        $like = new LikeCount;
        $like->where('photo_id',$this->id)->where('user_id',$user_id)->delete();
        $this->dispatch('refreshParent');
    }
    public function render()
    {
        return view('livewire.like-counter');
    }
}

My like-counter.blade.php Blade file:

<div>
    @if($like_exist != 1)
    <button type='button' class='button btn' wire:click='like'>Like...</button>
    @else
    <button type='button' class='button btn' wire:click='unlike'>Unlike...</button>
    @endif
    <p>{{ $like_count }} people liked this photo</p>
</div>

I expected that after clicking the Like/Unlike button, the wire:click event will trigger the method specified in my <button> element and then reloads the component to reflect the change in the component, but instead it does not refresh after the trigger and i need to do a full reload to get the updated results.

From this, i think there are three possible problems with my code:

  1. my like-counter.blade.php file is written incorrectly and i need to merge it into a single button with a toggle change (thus requiring my like() and unlike() method to merge)
  2. my refresh method in LikeCounter component doesnt work as it should

if neither of these are correct, how should i refactor my code?


Solution

  • The main issuee seems to be that $this->like_count and $this->like_exists are only called opun once when the mount() function is called. This function cant be refreshed and only be called once.

    solution 1:

    You can have the same kind of function as mount() like boot() which can be called opun a second time. which will fix the issue.

    solution 2:

    you can update the $this->like_count and $this->like_exists at the end of the functions like() and unlike() like this:

    class LikeCounter extends Component
    {
        public $id,$photo,$like_count,$like_exist;
    
        protected $listeners = [
            'refreshParent' => '$refresh',
          ];
          
        public function mount($id)
        {
            $this->id = $id;
            $this->photo = Photo::find($this->id);
            $this->like_count = LikeCount::count();
            if(LikeCount::where('user_id',Auth::id())->where('photo_id',$this->id)->get()->isEmpty() == false ){
                $this->like_exist = 1;
            }
            else{
                $this->like_exist = 0;
            }
        }
        public function like()
        {
            $this->photo = Photo::find($this->id);
            $user_id = Auth::id();
            $this->photo->likes()->create([
                'user_id' => $user_id,
                'photo_id'=> $this->photo->photo_id
            ]);
            $this->like_count = LikeCount::count();
            if(LikeCount::where('user_id',Auth::id())->where('photo_id',$this->id)->get()->isEmpty() == false ){
                $this->like_exist = 1;
            }
            else{
                $this->like_exist = 0;
            }
            $this->dispatch('refreshParent');
        }
        public function unlike()
        {
            $this->photo = Photo::find($this->id);
            $user_id = Auth::id();
            $like = new LikeCount;
            $like->where('photo_id',$this->id)->where('user_id',$user_id)->delete();
             $this->like_count = LikeCount::count();
            if(LikeCount::where('user_id',Auth::id())->where('photo_id',$this->id)->get()->isEmpty() == false ){
                $this->like_exist = 1;
            }
            else{
                $this->like_exist = 0;
            }
            $this->dispatch('refreshParent');
        }
        public function render()
        {
            return view('livewire.like-counter');
        }
    }