SashaB's avatar

Issue with child comp javascript when dynamically loading nested component

Hello! I'm new in forum and new in Laravel development. I have the followng problem. I try to load dynamically nested Livewire components from the parent Livewire componen like:

<div>
        @if ($caller==0)
            <livewire:comp1>
        @endif
        @if ($caller==1)
            <livewire:comp2 >
        @endif
    </div>

In the nested comp (day comp1) I have a vast js logic. As I work with statically nested components I always used

@push('scripts')
    <script>
        document.addEventListener("livewire:load", function(event) {
      //my js logic 

and it always worked out. For the dynamically bound nested components it never works because the event livewire:load has been fired before dynamically binding I think. If I comment out the eventlistener "livewire:load" it throuws the error "Livewire.hook is not a function" (my nested js logic contains hooks). So how can I bind the js logic (Livewire command like hooks included) for the dynamically loaded nested livewire component? Is there some other event I should listen to instead of livewire:load. Please give me a piece od advice.

0 likes
4 replies
kosta006's avatar

document.addEventListener("livewire: initialized", () => {});

Alpine is loaded on the first livewire component, whereas livewire: initialized is called on every component when its loaded. There is also 'livewire:init" which runs when the first component is loaded as well.

1 like
SashaB's avatar

@kosta006 Thank you for your help. I'm working woth Livewire 2.0. I dont use Alpine.js for my project. I have tried document.addEventListener("livewire: initialized", () => {}); it never fires an event, be it statically or runtime bound component. Livewire.hook("component.initialized", (component) => {if (component.name == 'myvompname') {} }); fires on the statically bound component, but not on the runtime bound. thats the great problem I have. I dont know how to load the javascript inside the dynamically bound component.

kosta006's avatar

@SashaB another way is to inject it manually. IN your blade component you have something like this:

window.addEventListener('chart-preloaded', event => { function loadJS(FILE_URL, async = true) { let scriptEle = document.createElement("script");

                scriptEle.setAttribute("src", FILE_URL);
                scriptEle.setAttribute("type", "text/javascript");
                scriptEle.setAttribute("async", async);

                document.body.appendChild(scriptEle);

                // success event
                scriptEle.addEventListener("load", () => {
                    @this.
                    chartLoaded = true;

                });
                // error event
                scriptEle.addEventListener("error", (ev) => {
                    console.log("Error on loading file", ev);
                });
            }

            loadJS("{{ asset('js/http_cdn.jsdelivr.net_npm_chart.js.js') }}", true);
        });
           				

Then in your component you fire off the event listener:

$this->dispatchBrowserEvent('chart-preloaded');

reeeen's avatar

I don't know if this helps but I found this article states to put all javascript into @script tags in livewire components. livewire.laravel.com/docs/javascript

1 like

Please or to participate in this conversation.