VincentCP's avatar

Laravel Livewire 3 Global Modal Issue: BindingResolutionException when using Livewire.dispatchTo

Hi! I have been trying to make a reusable global modal for confirmation purposes on livewire. I had encountered various issues in making this work.

My current situation is that I managed to make the modal working by having double roundtrip (from frontend-alpine -> my global modal component method call -> target component). I wanted to make it to be direct (frontend-alpine -> target component).

The issue I encountered when trying to do so is that the listener managed to receive the dispatched event, but the payload/data is not read properly and throw BindingResolutionException. I have checked that by allowing the parameter to be null/empty, the exception won't be thrown at all.

Can anyone tell me why and how to solve this issue? Thanks!

0 likes
12 replies
VincentCP's avatar

Does not work

			<button 
                x-on:click="
                    Livewire.dispatchTo(target, eventToEmit, payload);
                    close();
                "
                class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-1.5 rounded text-sm"
            >
                Confirm
            </button>

Working example (double roundtrip)

			<button 
                x-on:click="
                    $wire.confirm(eventToEmit, payload);
                    close();
                "
                class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-1.5 rounded text-sm"
            >
                Confirm
            </button>

	public function confirm($eventToEmit = null, $payload = [])
    {
        $this->eventToEmit = $eventToEmit;
        $this->payload = $payload;

        if ($this->eventToEmit) {
            $this->dispatch($this->eventToEmit, $this->payload);
        }
    }
valentin_vranic's avatar

I don't see where you listen for the global event itself, on for confirm method.

What if:

adding #[On('open-modal')] above public function confirm($eventToEmit = null, $payload = [])?

And it could be used like you mentioned in the beginning with wire:click="$dispatchTo('ConfirmationModal', 'confirm', {{$payload}})"

Am I missing something?

VincentCP's avatar

There is no problem with the confirm method. It works, but it causes server roundtrip twice (one, from the front-end to the modal component visa $wire.confirm(); two, from the modal component to the target component (task table) via dispatch on the confirm method.

What I want is to make it work directly from the frontend to the target table (task table), which I assume is through x-on:click $dispatch($event, $payload).

The current situation is that while the event got listened by the listener, the payload is not being read/processed correctly and that the exception BindingResolutionException is thrown by the listener when it is done directly via Alpine $dispatch method.

Using the $wire.confirm() method works just fine and the difference between this (2x roundtrip) vs via alpine (direct, 1x roundtrip) is just an extra of 100ms approximately.

I just can't understand why one works and that the other doesn't despite both managed to reach the listener.

The listener for open-modal is alpine based (x-on.open-modal.window), and its function is to open the modal with the payload sent (from front-end to front-end) as this modal is just a template for confirmation and I wanted to reduce unneeded server call whenever possible.

valentin_vranic's avatar
Level 5

Oh, okay. I think I figured it out.

Put the payload into [].

<button
        wire:click="$dispatchTo(target, eventToEmit, [payload])"
        class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-1.5 rounded text-sm"
>
    Confirm
</button>
VincentCP's avatar

Woah it works!!! Thank you very much.

I have a question, why do I need to warp it in [ ]? Is it because for a data such as payload, which usually is a set of data need to be received as an array? And mine was failing because I was using JSON wrapper { } instead of standard array?

valentin_vranic's avatar

Not aware of the cause, I had some similar approaches earlier in my codebase. And everywhere where I dispatch from js the [] were needed when passing params, so I tried and it worked.

But I agree, it's a bit strange behavior...

Please or to participate in this conversation.