[SOLVED] Livewire child components loaded by Jquery Ajax not working

Hi,

I’m creating a backinstock component. It’s a button rendering in a product list.
This list has got an Jquery pagination and I include the component for each products like this :

@livewire('stock-alert', ['product' => $product, 'warehouseId' => $warehouseId], key($product->id))

Only products loaded without Jquey Ajax work. The others not how can I do to make it work ? Refresh in each call of pagination in Jquery ?

Thanks

Hey @making-digital,

we need more information to be able to help you (more code espacially).

But the main question I have is, why do you load the products with jquery and why you don’t use the power of livewire for this?

I use Livewire in a old Laravel application. In order not to redevelop the whole thing. I’m using Livewire components as soon as I can for new features. The loop on products include component :2020-08-20_11-51-32

@livewire('stock-alert', ['product' => $product, 'warehouseId' => $warehouse_id], key(rand() * $product->id))

In Javascript we have a load_more function like this :

function load_more(){
        if(more == true) {
            $(".load-more").show();
            $.ajax({
                url: '{{ route('dolibarr-shop-home') }}',
                type:'get',
                dataType:'html',
                data:{
                    page:page
                },
                beforeSend:function(){
                    $(".load-more").show();
                },
                success:function(data){
                    if (data != 'false') {
                        $("#products > tbody:last-child").append(data);
                        $(".load-more").hide();
                        $('[data-toggle="tooltip"]').tooltip();
                    }else{
                        more = false;
                        $(".load-more").hide();
                    }
                }
            });
        }
    } 

This is an animated GIF to see the problem. I think we should refresh Livewire how can I do ?

Hey @making-digital,

ah i see :smiley:

Sadly the gif has become really small, it’s impossible to see anything.

Thank you for the jQuery code, but sadly that’s not enough. Where comes Livewire into play? Where do you attach new products coming from jQuery? What does the Livewire component do? How does jQuery interact with the Component?

Currently i could only make wild guesses on whats going on or not :smiley:

Hey maxeckel,

Sorry, I think the GIF is resized you could see this link :
The problem in video

products.blade.php

@foreach($products as $product)
@php
$discount = $discount_long = $discount_percent = null;
$price = number_format($product->multiprices[$thirdparty['price_level']] , 2, '.', ' ');
if (!empty($client->percent_discount)) {
    $price = $price - ($price * $client->percent_discount / 100);
    $price = number_format($price , 2, '.', ' ');
}
if ($product->hasDiscount($client) == true && session('type') != 'personalized') {
    $discount = $product->getDiscount($client);
    if (!empty($discount)) {
        $discount_long = __('global.discountof').' '.$discount['discount'].' % ';
        if (! empty($discount['date_order_start'])) {
            $discount_long.= (empty($discount['date_order_end']) ? __('global.as_of') : __('global.from')).' '.\Carbon\Carbon::parse($discount['date_order_start'])->format('d/m/Y').' ';
        }
        if (! empty($discount['date_order_end'])) {
            $discount_long.= (empty($discount['date_order_start']) ? __('global.until') : __('global.to')).' '.\Carbon\Carbon::parse($discount['date_order_end'])->format('d/m/Y');
        }
        $discount_percent = $discount['discount'];
        $price = number_format($price - ($price * ($discount['discount'] / 100)), 2, '.', ' ');
    }
}
@endphp
@if(!empty($product->multiprices[$thirdparty['price_level']]) && floatval($product->multiprices[$thirdparty['price_level']]) > 0 && $product->product_client->where('pivot.client_id', session('thirdparty')['id'])->where('pivot.active', 1)->count() == 0)
    @php
        $warehouse_id = 5;
        if (!empty($client) && ($client->warehouse_id == 1 || $client->warehouse_id == 5)){
            $warehouse_id = session('type') == 'personalized' ? 9 : $client->warehouse_id;
        }
        $stock = $product->getStockAndLabel($warehouse_id);
        @endphp

        @livewire('stock-alert', ['product' => $product, 'warehouseId' => $warehouse_id], key($product->id))
@endif

@endforeach

I’ve simplified the code and we have a call in Jquery to load more products. The products loaded does not work cause we have this kind of DOM here :

Instead of (working) :

Hey @making-digital,

thank you! Looking at your jquery ajax call, I guess you are rendering the new products server side and return the html for the newly loaded products and attach that to your list, am i right?

I guess this doesn’t work, as Livewire doesn’t know about the changes you have made through jQuery and doesn’t initialize the components properly. But i think you already came to the same conclusion, why you asked for the refresh of the component in your previous post.

I’ve had a quick look at the Livewire JS part. I haven’t tested or used it before, but you could maybe try to use “window.livewire.rescan()” after you have modified the DOM (see here: https://github.com/livewire/livewire/blob/97811b24aac6cf1e829f9dff7d7daac2122b81c7/js/index.js#L94).

Using this method, Livewire will rescan for components (as the name suggests). Hopefully it will init your newly added products, but i’m not sure about possible side-effects for your initially loaded ones.

2 Likes

Hi maxeckel,

I find the same method and it’s working ! start, restart does not change anything but rescan yes :wink:
Thanks for your help, really appreciate :wink:

Glad it’s working! I didn’t know about that method either before, we both learned something today :smiley: