rappasoft / laravel-livewire-tables

A dynamic table component for Laravel Livewire
https://rappasoft.com/docs/laravel-livewire-tables/v2/introduction
MIT License
1.7k stars 320 forks source link

[Bug]: The component class constructor doesn't seem to run when using ComponentColumn #1513

Open nathan-io opened 8 months ago

nathan-io commented 8 months ago

What happened?

We're trying to use a Blade component as a column:

            ComponentColumn::make('Fine Content', 'fine_weight_ozt')
                ->component('weight-with-conversions')
                ->attributes(fn ($value, $row, Column $column) => [
                    'weight' => new Weight($row->weighing_unit_type, $row->fine_weight),
                ]),

This does cause livewire-tables to attempt to render the component view, but it throws an "Undefined variable" exception because the public properties that are set in the constructor aren't present.

I don't believe the problem is in the component, because it works without issue when called in a view:

@php
     $weight = new App\Data\Weight(1, 1)
@endphp
<x-weight-with-conversions :weight="$weight" />

So perhaps the constructor is not firing?


Here's the component class and view:

...
class WeightWithConversions extends Component
{
    public Weight $weight;
    public string $conversions;

    /**
     * Create a new component instance.
     */
    public function __construct(Weight $weight)
    {
        $this->weight = $weight;

        $this->conversions =
            $weight->toString(WeighingUnitType::TroyOunce) . '<br/>' .
            $weight->toString(WeighingUnitType::Gram) . '<br>' .
            $weight->toString(WeighingUnitType::Pennyweight);
    }

    /**
     * Get the view / contents that represent the component.
     */
    public function render(): View|Closure|string
    {
        return view('components.weight-with-conversions');
    }
}

View:

<button data-popover data-tippy-content="{!! $conversions !!}" class="underline-dotted">
    {{ $weight->toString() }}
</button>

How to reproduce the bug

No response

Package Version

3.1.0

PHP Version

8.1.x

Laravel Version

10

Alpine Version

No response

Theme

None

Notes

No response

Error Message

No response

lrljoe commented 8 months ago

Thanks for raising, I'll have a look in a bit, just so I can confirm:

class WeightWithConversions extends Component

Is that: Livewire\Component or Illuminate\View\Component

I'm assuming the latter?

nathan-io commented 8 months ago

It's a Blade component.

<?php

namespace App\View\Components;

use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
use App\Data\Weight;
use App\Enums\Item\WeighingUnitType;

class WeightWithConversions extends Component
{
    public Weight $weight;
    public string $conversions;

    /**
     * Create a new component instance.
     */
    public function __construct(Weight $weight)
    {
        $this->weight = $weight;

        $this->conversions =
            $weight->toString(WeighingUnitType::TroyOunce) . '<br/>' .
            $weight->toString(WeighingUnitType::Gram) . '<br>' .
            $weight->toString(WeighingUnitType::Pennyweight);
    }

    /**
     * Get the view / contents that represent the component.
     */
    public function render(): View|Closure|string
    {
        return view('components.weight-with-conversions');
    }
}
lrljoe commented 8 months ago

Perfect, thanks, I'll take a look shortly.

lrljoe commented 8 months ago

Just having a look at why this isn't working for you, as I have a ComponentColumn working in my test environment. Will see if I can figure out why it works for me and not for you!

nathan-io commented 8 months ago

Thanks for looking into this!

I see one potential issue (weighing_unit_type has a cast), I'll investigate and update this.

nathan-io commented 8 months ago

I looked at it, still no luck. The Weight constructor throws an exception if supplied invalid arguments.

I put a dd() in the component constructor, but I don't get a dump when I view the page with the table. I move the dd() to the component view, and I do.

Can you show me your working test?

lrljoe commented 8 months ago

I'll have to share it tomorrow, as I'm tuckered out now: See Here for why! That should all get merged in, possibly tomorrow as a new release. But then I will definitely share my working example!

Although glancing at it, I think mine may be an anonymous component, which would explain a lot as to why mine is working and yours isn't.

I'll pop the code open tomorrow to see if I can figure out what's going on there.

nathan-io commented 8 months ago

Although glancing at it, I think mine may be an anonymous component, which would explain a lot as to why mine is working and yours isn't.

Yes I think this is the difference.

stale[bot] commented 6 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 5 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 4 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 3 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

nathan-io commented 2 weeks ago

This is still an issue

lrljoe commented 2 weeks ago

Apologies, stalebot gets a bit over-eager (I have no control over that!)

I'll do my best to take a look at this over the next week (so expect an update by the end of the month).

I have tinkered a little, and have got this resolved in my local environment (I've added a new Column type to avoid any conflicts with existing code).

If you want to give it a whirl, ping me on Discord and I'll let you know what to do to give it a test (would appreciate a real-world test tbh)

lrljoe commented 4 days ago

Please do reach out if you want to test this, as otherwise I'll throw it into the next version, and it may not do what you want!

nathan-io commented 4 days ago

Hello! I don't really use Discord, could you post some code here? I could temporarily modify my local vendor files and test it.

nathan-io commented 4 days ago

To test this, all you need is a component which has a class constructor that sets some variable. Then reference that variable in the component view to make sure it's available.