emitSelf not working with Javascript listener, but emit does?

Howdy, all. I’m new to Livewire, so the issue below may just be my misunderstanding of the workflow, but I wanted to reach out before butting against it for too much longer.

My eventual goal in using Livewire with my current project is to enable some more interesting user interactions with a Javascript charting library, amCharts, but I’ve abstracted my problem down to a basic component interaction shown below.

What seems to be the problem:

I have several identical components, each with a number input, a $number property, and an updatedNumber method. When the number is updated, I emit a test event, with listeners in the Javascript. That event just console logs the number.

When emitting the event, all duplicated components fire and log the number, which is expected. I would like all of the components to be self-scoped, with users interacting within them and modifying only that chart, so I’ve tested both emitSelf and emitUp, but the event listener does not respond in either situation.

These components are not created in a loop, but instead explicitly written in a blade, as below:

<livewire:test />
<livewire:test />
<livewire:test />

Looking at the docs, the emitSelf approach seems to be what I would want, though I get no resulting console logs.

Steps to Reproduce:

Create a test component and blade file.
On the component, add a number property, and updatedNumber method to emit an event.
In the blade, create a number input, and javascript to listen to the emitted event.
Update the number with a standard emit, and observe all expected events in the component fire.
Modify the event to emitSelf, and observe no events firing.

Are you using the latest version of Livewire:

“livewire/livewire”: “^1.3”,

Do you have any screenshots or code examples:

test.blade.php

<div>
    <input type="number" wire:model="number">
</div>

@push('scripts')
<script>
    window.livewire.on('thing', number => {
        console.log(number);
    })
</script>
    @endpush

Test.php

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Test extends Component
{

    public $number = 1;

    public function render()
    {
        return view('livewire.test');
    }

    public function  updatedNumber() {
        $this->emitSelf('thing', $this->number);
    }
}
1 Like

Here’s the issue: if you’re emitting to self, you can’t listen for the event on the window scope. I use alpine to listen for my scoped event. The blade looks like this:

component.blade.php

<div> {{-- root livewire --}}
    <div x-data x-init="@this.on('', () => { /** javascript here **/ })"> {{-- listen for events on component --}}
    </div>
</div>

edit: forgot to add x-data to initialize the alpine component.

2 Likes

Well butter my biscuits, that does make sense, doesn’t it?

I haven’t dug into the Alpine docs yet, so I think this will serve as my starting point. Much obliged!

Glad I could help. Alpine is super easy and verbose so it’s easily readable. Also, super light! Highly recommend coupling with livewire. You could also use vanilla js with @this.on but you need to make sure you’re loading your script after livewire has loaded or you’ll throw a not found error.

@this is a blade directive that replaces with window.find(caluculatedLivewireComponentId).

2 Likes

How can I make a div constantly lively, additionally reactivate it after a click on someplace else? Right now I loop trough each 500ms to reactivate it witch isn’t quality to browsers.I even have a jw player , and for the occasion listeners (like play or volume) to paintings it desires to be in an lively state. Oh that code hyperlink could be very cool! I am looking to upload a occasion listener to a reset button showing the textual content the shape has been submitted.