Search code examples
laravellaravel-livewire

How to get feedback on confirm dialog with Sweetalert2 on Livewire site?


Looking at this how to use sweetalert2 in livewire branch I try to make confirm dialog with Sweetalert2 on Livewire site

When from Livewire component I call:

public function sendConfirm()
        $this->dispatch('clientConfirm', [
            'type' => $type->value,
            'title' => $title ?? ConfigValueEnum::get(ConfigValueEnum::SITE_NAME),
            'message' => $message,
        ]);

    #[On('clientConfirmAction')] // I EXPECT THIS METHOD WOULD BE TRIGGERED ON CONFIRM
    public function clientConfirmAction()
    {
        dd('clientConfirmAction');
    }

I catch this event in app.js file :

window.addEventListener('clientConfirm', (event) => {
    console.log('clientConfirm event::')
    console.log(event)

    Swal.fire({
        icon: event.detail[0].type,
        title: event.detail[0].title,
        html: event.detail[0].message,
        showConfirmButton: true,
        showCancelButton: true,
        confirmButtonColor: '#d33',
        cancelButtonColor: '#33cc33',
        confirmButtonText: 'Yes'
    }).then((result) => {
        if (result.isConfirmed) {  // ON CONFIRM CALL METHOD ON LIVEWIRE SIDE
            Livewire.dispatch('clientConfirmAction', event.detail.id);
        } else {
            Livewire.emit('makeActionCancel', event.detail.id);
        }
    });
})

In this doc https://livewire.laravel.com/docs/javascript#the-livewire-global-object I see using of global object Livewire, but why method clientConfirmAction is not triggered?

Additive code

Yes, I fixed with Livewire.dispatch() in app.js file and with code:

window.addEventListener('clientConfirm', (event) => {
    console.log('clientConfirm event::')
    console.log(event)

    Swal.fire({
        icon: event.detail[0].type,
        title: event.detail[0].title,
        html: event.detail[0].message,
        showConfirmButton: true,

        showCancelButton: true,
        confirmButtonColor: '#d33',
        cancelButtonColor: '#33cc33',
        confirmButtonText: 'Yes'
    }).then((result) => {
        if (result.isConfirmed) {
            console.log('-1 Livewire::')
            console.log(Livewire)
            Livewire.dispatch('clientConfirmAction', 123 );
        } else {
            Livewire.dispatch('makeActionCancel', event.detail.id);
        }
    });

But method clientConfirmAction of my Livewire component is not triggered.

Also on "network" tab of my browser there are no any events (I suppose must be any as event is triggered/dispatched from JS side to Livewire) I see output in browser's console:

enter image description here

Could the issue be that I use resources/js/app.js for defining window.addEventListener?

"laravel/framework": "^10.48.4",
"livewire/livewire": "^3.4.9",

Solution

  • I tested your code and the clientConfirmAction event is dispatched regularly. You must make sure that you have imported the class that manages the #[On] attribute:

    <?php
    
    namespace App\Livewire;
    
    use Livewire\Attributes\On;  // <~~ THIS!
    use Livewire\Component;
    
    class MyClass extends Component
    {
    .....
    

    Furthermore, the Swal example you use refers to Livewire 2, so you must change Livewire.emit() with Livewire.dispatch() even when sending the makeActionCancel event and the event data must be encoded as well with a key-value JSON object, whose key must match the name of the parameter of the PHP method that intercepts the event. On the PHP side, since the dispatch() method accepts named arguments, you can avoid to enclose them in an array.

    window.addEventListener('clientConfirm', (event) => {
    
        Swal.fire({
    
            icon: event.detail.type,
            title: event.detail.title,
            html: event.detail.message,
            showConfirmButton: true,
            showCancelButton: true,
            confirmButtonColor: '#d33',
            cancelButtonColor: '#33cc33',
            confirmButtonText: 'Yes'
    
        })
    
        .then((result) => {
    
            if (result.isConfirmed) {
                Livewire.dispatch('clientConfirmAction', {id: event.detail.id});
            } else {
                Livewire.dispatch('makeActionCancel', {id: event.detail.id});
            }
        });
    })
    
    <?php
    
    namespace App\Livewire;
    
    use Livewire\Attributes\On;
    use Livewire\Component;
    
    class MyClass extends Component
    {
        public function sendConfirm($type, $message, $title = NULL)
        {
    
            $this->dispatch('clientConfirm',
                type: $type->value,
                title: $title ?? ConfigValueEnum::get(ConfigValueEnum::SITE_NAME),
                message: $message,
                id: 123
            );
        }
    
    
        #[On('clientConfirmAction')]
        public function clientConfirmAction ($id)
        {
            dd('clientConfirmAction', $id);
        }
    
        #[On('makeActionCancel')]
        public function clientCancelAction ($id)
        {
            dd('makeActionCancel', $id);
        }
    }