rappasoft/laravel-livewire-tables

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

nathan-io opened this issue · 53 comments

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

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?

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');
    }
}

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

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!

Thanks for looking into this!

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

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?

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.

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.

Hi, wanted to see if you've had any chance to take a look at this. Thank you!

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.

Don't close :)