[Bug]: enum columns don't work in v3
nikosid opened this issue · 4 comments
What happened?
After upgrade to v3 I get the error:
Rappasoft\LaravelLivewireTables\Views\Column::getContents(): Return value must be of type Illuminate\Support\HtmlString|Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException|Illuminate\Contracts\Foundation\Application|Illuminate\Contracts\View\Factory|Illuminate\Contracts\View\View|string|null, App\Enums\UrlSource returned
This happens because I have this column configured:
Column::make('Source', 'source')->sortable(),
In my model there is this cast:
protected $casts = [
'source' => UrlSource::class,
];
and class UrlSource looks like this:
<?php
namespace App\Enums;
enum UrlSource: string
{
case WEB = 'web';
case API = 'api';
}
How to reproduce the bug
No response
Package Version
v3.0.0.-beta.4
PHP Version
8.2.x
Laravel Version
10.28.0
Alpine Version
No response
Theme
None
Notes
This worked in version 2*
Error Message
Rappasoft\LaravelLivewireTables\Views\Column::getContents(): Return value must be of type Illuminate\Support\HtmlString|Rappasoft\LaravelLivewireTables\Exceptions\DataTableConfigurationException|Illuminate\Contracts\Foundation\Application|Illuminate\Contracts\View\Factory|Illuminate\Contracts\View\View|string|null, App\Enums\UrlSource returned
maybe using format works?
Column::make('Source', 'source')
->sortable()
->format(fn ($value) => $value->value)
Question - if I adjust the return type to accept an Enum, and use:
Column::make('Source', 'source')->sortable(),
I'll just get the value (i.e. not a name/label etc), is that your desired outcome?
If you want to access something else on the Enum class:
Let's wind it back a tiny bit! The Table Package will return fields, based on what is in your Table, and setAdditionalSelects.
When you use a "make" with a second value, it'll try to find that field in the model (or via a relation using dot notation). When it finds it, it adds that value into the Builder query, and will return that as a raw value, and it won't go through the typical model casting etc.
If you want to use an Enum Cast, and return a method on your Enum class (e.g. a label etc), then the way to achieve what you want is using:
- A Label Column, and use the label method to tell the table what you want out of it, e.g.
Column::make('Source')->sortable()
->label(
fn($row, Column $column) => $row->source->name
),
or
Column::make('Source')->sortable()
->label(
fn($row, Column $column) => $row->source->value
),
- Adding the relevant field into the setAdditionalSelects() so that you have access to the raw value
public function configure(): void
{
$this->setPrimaryKey('id')
->setAdditionalSelects(['articles.id as id', 'articles.source'])
}
So I've added the return type hint in, so that you won't receive the error, that's in v3-develop now, and will go into a new beta release in the next day or two.
Interested to know your use case for it though, and whether an EnumColumn or similar would be useful going forward (for example - allowing you to specify which method you want to call on the column).
Fix for return type is in v3.0.0-beta.5