F
Filamentโ€ข8mo 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(),
]);
}
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}"))
@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');
}
}
<?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>
<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....
Jump to solution
4 Replies
Josh
Joshโ€ข8mo ago
Oops forgot the screen recording!
Josh
Joshโ€ข8mo ago
Still trying to figure out what is up. Other issues with similar errors give a potential fix by using wire:key however I have; @livewire('player-avatars', ['uuid' => $getRecord()->minecraft_uuid, key('player-avatar-' . $getRecord()->id) Unsure how to fix at this stage :/
Solution
Josh
Joshโ€ข8mo ago
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()))
@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. ๐Ÿš€
KeyMe
KeyMeโ€ข6mo ago
@Josh excuse me for tagging u josh, facing similar issue, but in my case, i display three different livewire components passed to viewfields in resource view. The behaviour was whenever i click on a page action or change relationmanager tabs, the last rendered component disappear and I received the same uncaught snapshot error. Do you perhaps have any clue on figuring this out? Again sorry.
Want results from more Discord servers?
Add your server
More Posts