最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Can't refresh a Livewire component after wire:click button - Stack Overflow

programmeradmin0浏览0评论

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?

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?

Share Improve this question edited Nov 21, 2024 at 4:26 jakesnowdrop asked Nov 20, 2024 at 6:42 jakesnowdropjakesnowdrop 156 bronze badges 10
  • the main function that wil display/update the new count of likes is called mount() when you go to the official livewire docs and then to the rendering of components you wil find In Livewire components, you use mount() instead of a class constructor __construct() like you may be used to. NB: mount() is only ever called when the component is first mounted and will not be called again even when the component is refreshed or rerendered. – oelimoe Commented Nov 20, 2024 at 8:08
  • @oelimoe this gives me the idea to both merge my like() and unlike() method into my mount() method. I use livewire 3.x but the docs on the usage of mount() method remains similar. However, i still want to display the change after triggering the method, not after a full page reload. should i use the boot()method to display the change? – jakesnowdrop Commented Nov 21, 2024 at 1:44
  • @oelimoe Correction: actually i need to put my like() and unlike() method into a new method. However, i was thinking that the problem might not be on the mount() itself but rather how the data is presented in the blade view, thus i might not need to merge my like() and unlike() method at all if possible. – jakesnowdrop Commented Nov 21, 2024 at 3:22
  • combining the like and unlike method isnt an issue since it is just an if statement checking if user has liked. I couldnt test this code myself since i had no real database like you did but what i did test is how like and dislike could work. so what i tried was in the like function i did $this->like_count += 1; and in the dislike it was $this->like_count -= 1 and set the $this->like_exists to 0 or 1 depending on it having like in the blade i changed nothing. The result of this was that it showed '1 people liked this post' and when disliked '0 people like this post' – oelimoe Commented Nov 21, 2024 at 8:14
  • so it did get updated when it was changed in the like method. then i was looking for when it would change in your code it was only when mount() was called that the like count got an update. and this function cant be refreshed so it only changes when you open the page not when code is executed – oelimoe Commented Nov 21, 2024 at 8:16
 |  Show 5 more comments

1 Answer 1

Reset to default 0

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');
    }
}
发布评论

评论列表(0)

  1. 暂无评论