I'm using Filament, Livewire 3 and Laravel 11.
I stumbled upon a situation where the table method is being executed before my updateLocation method.
I added a dump to see the sequence and the result is 2, 1, 1, 1. I also don't understand why the updateLocation is executed 3 time but that is not the issue for this question.
Problem is, when is change my location on my other livewire component and dispatch
$this->dispatch('update-location', location: $this->location); my table is not updated as expected because, table is updated before the new myLocation has been set.
I hope someone knows a different approach or has some tips on how to refresh the filament table. Already tried $this->dispatch('$refresh'); but did not work
My class looks like this:
<?php
namespace App\Livewire;
use App\EnumClasses\CountryCodes;
use App\Models\Place;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Tables\Actions\Action;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Filters\Filter;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Builder;
use Livewire\Attributes\On;
use Livewire\Component;
class ListPlaces extends Component implements HasForms, HasTable
{
use InteractsWithTable;
use InteractsWithForms;
/**
* @var array|float[]
*/
public array $myLocation;
public $shouldRenderTable = false;
public function mount(): void
{
$this->myLocation = [14.426422119140625, 50.06524954828362]; //longitude, latitude
}
public function updated(): void
{
$this->dispatch('update-place-filters', filterValues: $this->tableFilters);
}
#[On('update-location')]
public function updateLocation(array $location): void
{
dump(1);
$this->myLocation = $location;
}
public function table(Table $table): Table
{
$countryOptions = CountryCodes::COUNTRY_CODES;
$countryOptions = array_flip($countryOptions);
$countryOptions = $this->translateArray($countryOptions);
dump(2);
return $table
->query(Place::query()
->selectDistanceTo($this->myLocation)
->with('reviews')
)
->modelLabel('Plaats')->pluralModelLabel('Plaatsen')
->columns([
TextColumn::make('title')
->extraAttributes(fn(Place $record): array => [
'onmouseenter' => sprintf('dispatch(\'highlight-marker-event\', { id: \'%s\', title: \'%s\' })', $record->id, $record->title),
'onmouseleave' => sprintf('dispatch(\'remove-highlight-marker-event\', {id: \'%s\'})', $record->id)
])
->label(__('place.Title'))
->sortable(),
TextColumn::make('distance')
->label(__('place.Distance'))
->formatStateUsing(fn (string $state): string => round($state / 1000, 2) . ' Km'),
TextColumn::make('last_review')
->name('created_at')
->label(__('place.Last review'))
->formatStateUsing(fn (Place $record): string => $record->reviews->last()?->created_at?->format('d-m-Y') ?? '' )
])
->filters([
Filter::make('has_children_games')
->label(__('place.Has children games'))
->toggle()
->query(fn (Builder $query): Builder => $query->where('has_children_games', true)),
SelectFilter::make('country')
->label(__('place.Country'))
->multiple()
->options($countryOptions)
->attribute('country_iso'),
Filter::make('max_price')
->label(__('place.Max price'))
->form([
TextInput::make('max_price'),
])
->query(function (Builder $query, array $data): Builder {
return $query
->when(
$data['max_price'] ?? '',
fn (Builder $query, $price): Builder => $query->where('parking_price', 'like', '%'.$price.'%'),
);
}),
Filter::make('radius')
->label(__('place.Radius'))
->form([
TextInput::make('radius'),
])
->query(function (Builder $query, array $data): Builder {
return $query
->when(
$data['radius'] ?? '',
fn (Builder $query, $radius) : Builder => $query->withinDistanceTo($this->myLocation, $radius * 1000),
);
})
])
->filtersFormSchema(fn (array $filters): array => [
Section::make(__('place.Location'))
->schema([
$filters['country'],
$filters['radius']
])->collapsed(),
Section::make(__('place.Services'))
->schema([
$filters['has_children_games'],
])->collapsed(),
Section::make(__('place.Terrain'))
->schema([
$filters['max_price'],
])
->collapsed(true)
])->defaultSort('distance')
->actions([
Action::make('show')
->label(__('place.Details'))
->button()
->outlined()
->action(fn(Place $record) => $record->advance())
->modalContent(fn(Place $record): View => view(
'filament.place.detail',
['place' => $record],
))
->modalSubmitAction(false)->modalCancelAction(false)
])
->bulkActions([
// ...
]);
}
public function render(): View
{
return view('livewire.list-places');
}
}