rappasoft / laravel-livewire-tables

A dynamic table component for Laravel Livewire
https://rappasoft.com/docs/laravel-livewire-tables/v2/introduction
MIT License
1.7k stars 320 forks source link

[Bug]: Livewire component in Datatable: Snapshot missing on Livewire component with id... #1644

Closed mLicorn closed 3 months ago

mLicorn commented 5 months ago

What happened?

I'd like to use Livewire components in an array. My initial requirement is to display a hidden row when I click on an icon in a column. This row loads another table.

I managed to implement this with Livewire 2, but since version 3 I've been getting an error when I try to sort by a column: 'Snapshot missing on Livewire component with id.'. The interior of the component is deleted, leaving only the wire:id attribute.

error-min html-min

I've simplified the test by simply trying to display a Livewire component in a column. After several tests, I can't use a Livewire component in the datatable..

I'm probably doing something wrong, but I can't work out what.

How to reproduce the bug

  1. Create a new Laravel project: migrate and seed database
  2. Install Livewire 3
  3. Install Laravel Livewire Tables
  4. Create TestChild component
    
    <?php

namespace App\Livewire;

use Livewire\Component;

class TestChild extends Component { public int|string|null $index = null; public int|string|null $parent = null;

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

}

```blade
<div wire:key="test-child-component-{{ $parent }}-{{ $index }}">CHILD {{ $index }} !!</div>
  1. Create UsersTable
    
    <?php

namespace App\Livewire;

use App\Models\User; use Rappasoft\LaravelLivewireTables\DataTableComponent; use Rappasoft\LaravelLivewireTables\Views\Column;

class UsersTable extends DataTableComponent { protected $model = User::class;

public function configure(): void
{
    $this->setPrimaryKey('id');
}

public function columns(): array
{
    return [
        Column::make('ID', 'id')
            ->sortable()
            ->searchable(),

        Column::make('Name')
            ->sortable()
            ->view('datatables.columns.test')
            ->searchable(),

        Column::make('E-mail', 'email')
            ->sortable()
            ->searchable(),
    ];
}

}

6. Create view: datatables.columns.test
```blade
@aware(['tableName'])
@props(['row'])

<div wire:key="column-test-child-{{ $tableName . '-' . $row->id }}">
  <livewire:test-child
    index="{{ $row->id }}"
    :parent="$tableName"
  />
</div>
  1. Display Datatable in Welcome page
    <div><livewire:users-table /></div>
  2. Sort by Name: error

step-1-min step-2-min

Package Version

3.2.0

PHP Version

8.1.x

Laravel Version

10.40.0

Alpine Version

3.13.3

Theme

Tailwind 3.x

Notes

I've left all the default settings except for the database connection.

Error Message

Uncaught Snapshot missing on Livewire component with id: ...

lrljoe commented 5 months ago

Firstly - apologies for the delay in coming back to you, I've been away for a bit.

So you're loading in a Livewire Component as the content of a Column, and getting that error? Which version of Livewire are you using out of interest, so that I can try to replicate it properly.

Worth noting - it will always be sluggish trying to have 25/50/100 Livewire Components on a page, that's a Livewire things rather than a package thing. What's your end goal with it, as there may be a neater solution. It's one of the reasons we didn't introduce the Livewire Component Column, as on larger tables (100/200 rows in view), it was really low performance when re-rendering.

mLicorn commented 5 months ago

Thanks for your reply.

My first goal was to create a sub-row that loads another Datatable on demand (by clicking on an icon in a column).

Finally I created a component outside the Datatable that dynamically inserts and displays the row with AlpineJS.

stale[bot] commented 4 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.