wireui / wireui

TallStack UI components
https://v1.wireui.dev
MIT License
1.37k stars 166 forks source link

Confirm dialog calls method twice? #197

Closed nearueng closed 1 year ago

nearueng commented 2 years ago

Describe the bug Using the confirm dialog inside a livewire component e.g. $this->dialog()->confirm(), calls the 'accept' or 'reject' methods twice.

To Reproduce Steps to reproduce the behavior:

  1. Create a livewire component with a confirm dialog
  2. Have the accept method get called
  3. Store something arbitrary in the database to see how many times the method was called (e.g. a counter)

Expected behavior The method should only be called once after confirming. For example, if I'm building a request approval flow, and the acceptance of the confirm dialog should accept the request, right now, it is being accepted twice (and fails validation if I check for an existing acceptance).

Additional context On v0.15.0

putera commented 2 years ago

Look good to me. I cannot get the error. Please share your code.

nearueng commented 2 years ago

It's pretty standard. Here are the relevant parts.

Button to toggle the confirm dialog in livewire

 <x-buttons.edit tooltip="Approve this booking request" class="p-0 text-xs hover:bg-green-600" wire:click="confirmApprove">
        <x-icon name="check" class="h-4" />
    </x-buttons.edit>

Confirm dialog

public function confirmApprove()
    {
        $this->dialog()->confirm([
            'title'       => 'Approve this booking request?',
            'description' => 'The user will be notified and they will be able to complete their booking',
            'icon'        => 'question',
            'accept'      => [
                'label'  => 'Yes, approve',
                'method' => 'approve'
            ],
            'reject' => [
                'label'  => 'Cancel',
            ],
        ]);
    }

Approve function. The conditional throws an error if the request has already been approved or declined. Placing dump() tags outside of the conditional, and then a dd() inside shows that the dump tags get executed, the request gets approved, and the function runs again to be caught within the conditional. The dd() is then also visible.

public function approve()
    {
        if ($this->bookingRequest->isAlreadyApprovedOrDeclined()) {
            $this->handleRequestAlreadyApprovedOrDeclined();

            return;
        }

        ApproveBookingRequestAction::run($this->bookingRequest);

        $this->dialog()->show([
            'title' => 'Booking request approved',
            'description' => 'Awesome! This booking request was approved and the user was notified',
            'icon' => 'success'
        ]);

        $this->emit('bookingRequestUpdated');
    }
nearueng commented 2 years ago

Also, this is as good a place as any to say that I can't toggle the confirm dialogs through Alpine (hence why I resorted to doing them through livewire in the first place).

putera commented 2 years ago

is this problem solved ?

try to use this

wire:click.prevent="confirmApprove"
PH7-Jack commented 1 year ago

@nearueng This issue is inactive for a long time, I'm closing it now. If you still have this error comment "RE-OPEN" and tag me.

PH7-Jack commented 1 year ago

@putera thanks a lot for all of your work in the WireUI ❤️

anantrp commented 1 year ago

@putera @PH7-Jack I am facing the same issue, is it a common gotcha that I am missing?

Component :

<?php

namespace App\Http\Livewire\Credentials;

use Livewire\Component;
use WireUi\Traits\Actions;
use Illuminate\Support\Facades\Log;

class ListItem extends Component
{
    use Actions;

    public $credential;

    public function mount($credential) {
        $this->credential = $credential;
    }

    public function render()
    {
        return view('livewire.credentials.list-item');
    }

    public function onFetch() {
        Log::info('clicked onFetch');

        $this->dialog()->confirm([
            'title'       => 'Are you Sure?',
            'description' => 'Are you sure you want to fetch records?',
            'acceptLabel' => 'Yes, fetch it',
            'method'      => 'fetch',
        ]);
    }

    public function fetch($a = null, $b = null) {
        Log::info('run fetch');
        Log::info($a);
        Log::info($b);
    }
}

Markup : (this is inside a looped livewire component with foreach inside another livewire component)

<a href="#" class="text-green-600 dark:text-green-500 hover:underline mr-3" wire:click.prevent="onFetch">Fetch Records</a>

PH7-Jack commented 1 year ago

@anantrp If you have the same error, consider creating a new issue with the max of details possible.