Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply loading state only to particular component in livewire

I'm using Laravel Livewire in my project, I use wire:loading for loading the state while clicking. I iterated all the tasks in foreach loop but the loading state applies for all components. Here is the code.

enter image description here

Blade file

GitLab: https://gitlab.com/tasklog/tasklog/-/blob/master/resources/views/livewire/home/tasks.blade.php

<button type="button" wire:click="togglePraise({{ $task->id }}, {{ $task->user->id }})">
    👏
    <span class="small text-black-50 font-weight-bold">
        {{ $task->task_praise->count() }}
    </span>
    <div wire:loading wire:target="togglePraise">
        Processing...
    </div>
</button>

Controller file

GitLab: https://gitlab.com/tasklog/tasklog/-/blob/master/app/Http/Livewire/Home/Tasks.php

public function togglePraise($id, $user_id)
{
    if (Auth::check()) {
        if (Auth::user()->id === $user_id) {
            session()->flash('message', 'Forbidden!');

            return;
        }
        $isPraised = TaskPraise::where([
            ['user_id', Auth::user()->id],
            ['task_id', $id],
        ])->count();
        if ($isPraised === 1) {
            TaskPraise::where([
                ['user_id', Auth::user()->id],
                ['task_id', $id],
            ])->delete();

            return true;
        } else {
            TaskPraise::create([
                'task_id' => $id,
                'user_id' => Auth::user()->id,
            ]);

            return true;
        }
    } else {
        return session()->flash('message', 'Forbidden!');
    }
}
like image 769
Yogi Avatar asked Jul 19 '20 04:07

Yogi


People also ask

How do I enable flex and grid in Livewire?

By default, Livewire set's a loading element's "display" CSS property to "inline-block". If you want Livewire to use "flex" or "grid", you can use the following modifiers. You can also "hide" an element during a loading state using the .remove modifier.

Can I load HTML content in a livewire modal?

I can successfully load the HTML content in the modal, but any Javascript on the "target" component is not executed. So in the above code, when a user clicks the a tag, it will open the modal, placed in: As you can see, the modal component simply refers to another Livewire component called tasks.show.

Why does $loading = true not work with Livewire?

I think it's because livewire runs the whole function in one round trip AJAX request. So essentially loading = true will never be the case in your template. Yeah, that's it. Livewire will run all of your actions and then run the render method, so your template will receive $loading as false.

Why should I use Livewire for my App?

Because Livewire makes a roundtrip to the server every time an action is triggered on the page, there are cases when the page may not react immediately to a user event (like a click). Livewire allows you to easily display loading states, which can make your app feel more responsive.


Video Answer


1 Answers

I know the question was before the realease of v2, yet adding the answer for v2 for reference.

as per the Livewire docs if you're using v2, you may specify the action and its parameters in the wire:target directive. For your example, it would be like this:

wire:target="togglePraise({{ $task->id }}, {{ $task->user->id }})"
like image 198
Fahd Yousri Avatar answered Oct 10 '22 03:10

Fahd Yousri