FilamentF
Filamentโ€ข3y ago
Josh

Snapshot Missing - View Column with Livewire Component

Evening!

After some wisdom from you smart people!
I have a table defined on my PlayerResource with a
ViewColumn
that had a custom view;
public static function table(Table $table): Table
    {
        return $table
            ->columns([
                ViewColumn::make('username')
                ->label('Player')
                ->searchable()
                ->sortable()
                ->view('admin.players.columns.username'),
                TextColumn::make('last_login_at')
                ->label('Last Login')
                ->sortable(),
            ]);
    }


Within the custom view I am calling a Livewire Component as seen below
  @livewire('player-avatars', ['uuid' => $getRecord()->minecraft_uuid], key("player-{$getRecord()->id}"))


This is the Livewire Component content
<?php

namespace App\Livewire;

use Livewire\Component;
use App\Helpers\MinecraftHelper;

class PlayerAvatars extends Component
{
    public $uuid;
    public $avatar;

    public function mount($uuid)
    {
        $this->uuid = $uuid;
        $this->avatar = '/storage/avatars/steve.png';
    }

    public function loadAvatar()
    {
        // Load the real avatar asynchronously
        $this->avatar = MinecraftHelper::getPlayerHead($this->uuid);
    }

    public function render()
    {
        return view('livewire.player-avatars');
    }
}


<div>
    <img wire:init="loadAvatar" src="{{ $avatar }}" alt="Player Avatar" class="relative w-9 h-9 mx-3 rounded-md" width="36" height="36">
</div>


It works perfectly for the most part however I noticed that when I have per page as all, change it down to a smaller amount like 10, go to the next page and change it back to all it will fail to get and display the avatars from the page I had just been on.

I recieve the error
Uncaught Snapshot


Is this something im doing or a limitation in filament? After any guidance!
See screen recording for demonstration ๐Ÿ™‚
Solution
The Problem:
I was facing an issue where Livewire components were not rendering correctly when changing the pagination state of a Filament table. Specifically, when I switched from page 2 to 'all' records, the avatars for some records weren't loading properly.

The Solution:
After diving into the Livewire and Filament documentation, I realised the problem was with how Livewire handles dynamic components. The key was to make each Livewire component instance unique for every render, especially when pagination states change.

I used Livewireโ€™s
wire:key
directive to uniquely identify each instance of my player-avatars component. The key was to include the current pagination page number in the wire:key attribute. This way, every time the page number changes, Livewire knows to re-render the component.

@livewire('player-avatars', ['uuid' => $getRecord()->minecraft_uuid, 'class' => 'w-9 h-9 mr-3 rounded-md'], key('player-avatar-' . $getRecord()->id . '-' . $this->getTableRecords()->currentPage()))


By appending
getTableRecords()->currentPage() 
to the
wire:key
, each avatar component is now tied not only to the record's ID but also to the current page number. This ensures proper re-rendering when the pagination state changes.

Why This Works:
Livewire needs to uniquely identify each component instance to manage its lifecycle effectively, especially when dealing with dynamic content like pagination. By adding the current page number to the
wire:key
, we help Livewire understand when it needs to refresh the components, ensuring our UI stays in sync with our application's state.

Hope this helps anyone who might be facing similar issues. ๐Ÿš€
Was this page helpful?