filament: Query string includes all available filters causing an error on refresh

Package

filament/filament

Package Version

v3

Laravel Version

v9.19

Livewire Version

v3

PHP Version

PHP 8.1

Problem description

In v3 when you select a filter, the query string will then populate with all the available filters, setting the others to null. While this pollutes the query string, the bigger issue is that with certain types of filters if you then refresh the page you will get an error as null is not an acceptable value.

In v2, only the active filter would be present in the query string.

Expected behavior

The query string should only include active filters

Steps to reproduce

  1. On the users page of the demo app filter by just one of the two dates, leaving the other date field alone.
  2. The query string will populate with the unfiltered date setting it to null: http://demov3.test/users?tableFilters[created_at][created_from]=2023-07-01&tableFilters[created_at][created_until]=null
  3. Refresh the page
  4. Error: Could not parse 'null': Failed to parse time string (null) at position 0 (n): The timezone could not be found in the database

Reproduction repository

https://github.com/archilex/demo

Relevant log output

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 3
  • Comments: 32 (29 by maintainers)

Most upvoted comments

@archilex, Thank you for addressing this issue. It’s a significant bug for my application, making all tables filters almost unusable. I hope we can find a solution soon. ❤️

So I also encountered problems when dealing with Toggle/Checkbox filters. Livewire doesn’t convert “true”/“false” to bool values, so the filters don’t work. Here’s the updated code:

public function boot(): void
{
    if ($this->tableFilters) {
        $this->replaceNullValues($this->tableFilters);
    }
}

protected function replaceNullValues(array &$data): void
{
    foreach ($data as &$value) {
        if (is_array($value)) {
            $this->replaceNullValues($value);
        } elseif ($value === 'null') {
            $value = null;
        } elseif ($value === 'false') {
            $value = false;
        } elseif ($value === 'true') {
            $value = true;
        }
    }
}

In light of Caleb’s comment that he won’t be able to address this in Livewire in the near future, should I look at implementing a temporary fix in Filament until it’s fixed in Livewire?

Even though the dateFilter is no longer throwing errors, this is still a problem with SelectFilter, TrashedFilter, TernaryFilter, and Filter with forms with textFields on refresh.

All my tables extend a BaseTableComponent. So, until we find a solution on Livewire, I’ve mitigated the issue by doing this:

public function boot(): void
{
    $this->replaceNullValues($this->tableFilters)
}

protected function replaceNullValues(array &$data): void
{
    foreach ($data as &$value) {
        if (is_array($value)) {
            $this->replaceNullValues($value);
        } elseif ($value === "null") {
            $value = null;
        }
    }
}

I know this isn’t beautiful, but it works for now. Haha!

Yes please. I am running into the same issue 😦

@KennedyTedesco Oh, I didn’t know about the standalone mode. The code works OK (for Filament full admin) as I posted it and fixed the issue. Thanks again for your snippet!

@jvitasek Oh, you’re right. It’s because I use Filament components (tables, forms, etc) in a standalone mode inside Livewire components, so, in my case, tableFilters are always defined. In your case, I don’t know where you should put this, because I have never used Filament full admin mode. I hope someone here can guide you.

@KennedyTedesco This didn’t work for me exactly, had to add a check for tableFilters (otherwise got errors), but thanks for the help! Also I didn’t know where to put this code right away.

In the list resource page, e.g. OrderResource/Pages/ListOrders.php:

public function boot(): void
{
    if ($this->tableFilters) {
        $this->replaceNullValues($this->tableFilters);
    }
}

protected function replaceNullValues(array &$data): void
{
    foreach ($data as &$value) {
        if (is_array($value)) {
            $this->replaceNullValues($value);
        } elseif ($value === "null") {
            $value = null;
        }
    }
}

Ok, for real this time, I can confirm that this is indeed a livewire bug. I’ve filed a failing test on livewire. My previous browser test wasn’t testing the actual problem, but I’ve worked out another test that consistently shows the issue.

https://github.com/filamentphp/filament/assets/315603/b4a47198-174b-49b4-8891-75abffb68af4

I think with this new Livewire, default state need to be set as empty string "", not null.

Thanks @ariaieboy for your work on the LW issue and failing test to get this fixed!

So are we sure this is 100% a Livewire bug? And if so, is there a workaround or not?

if you set the history to true it will not change the value to null so the problem will fixs for now but it’s a bug that must be fixed by livewire. And it’s not related to livewire backend and I am not that good with JS stuff.

I’ve created a bug report on livewire repo https://github.com/livewire/livewire/discussions/5932