symfony / ux

Symfony UX initiative: a JavaScript ecosystem for Symfony
https://ux.symfony.com/
MIT License
820 stars 298 forks source link

[LiveComponent] Property does not exist exception when a LiveProp object has a virtual method? #1589

Open gremo opened 6 months ago

gremo commented 6 months ago

My object is set as a LiveProp inside a Live component. It's a plain DTO with a method added, a virtual one, named getDiscountedUnitPrice:

<?php

namespace App\Model;

class Product
{
    use ModelFromArrayTrait;

    public ?string $id = null;
    public ?string $name = null;
    public ?bool $enabled = null;
    public ?bool $discountable = null;
    public ?DiscountInterface $discount = null;

    public function getDiscountedUnitPrice(): ?float
    {
        return $this->discount?->calculate($this->unitPrice) ?? $this->unitPrice;
    }
}

As soon as my DTO become a LiveProp, I get the following error:

Property App\Model\Product::$discountedUnitPrice does not exist

If you name the method discountedUnitPrice it works like a charm. I think this is a bug to be addressed.

smnandre commented 6 months ago

Could you show us how you call this method from your template ?

gremo commented 6 months ago

@smnandre thanks for helping, I'm not even printing the product in my template. The error is raised from a live listener:

    #[LiveProp]
    public ?Product $product = null;

    #[LiveListener("barcode_scanned")]
    public function onScan(#[LiveArg()] string $value): void
    {
        $envelope = $this->messageBus->dispatch(
            new FetchProductMessage($value, $this->order->customer, $this->profile)
        );
        $product = $envelope->last(HandledStamp::class)->getResult();

        $this->product = $product;
    }
smnandre commented 6 months ago

You may need to show more code, because i see nowhere where is the $discountedUnitPrice call mentionned in your error.

At least you should give a bit more details concerning this exception, where it is raised, etc.

gremo commented 6 months ago

Here is a screenshot, if it may help. I'm not using product in my template, in fact the error is related to the hydration process.

image

smnandre commented 6 months ago

So we can close this issue, as it's replaced by https://github.com/symfony/ux/issues/1590 right ?

gremo commented 6 months ago

There are two different issues, just naming are similar, a bit confusing Indeed...

gremo commented 6 months ago

@smnandre to be clear: I get that error for any "virtual" property of my DTO.

It may be related to the hydration problem explained here, because Symfony doesn't know how to set back the value when the hydrate occurs (and indeed it looks for a property named discountedUnitPrice, which doesn't exists).

It would be a nice idea to allow to exclude those "virtual properties". What If I only need getDiscountedUnitPrice on the server and not on the client?

For example "Do not try to dehydrate/hydrate this property":

#[LiveIgnore]
public function getDiscountedUnitPrice(): ?float
{
    return $this->discount?->calculate($this->unitPrice) ?? $this->unitPrice;
}
carsonbot commented 1 week ago

Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?

gremo commented 1 week ago

I think isn't resolved yet.

smnandre commented 1 week ago

Could you please create a small reproducer (the minimal app possible to reproduce / observe / investigate the bug) ?

It really is the best method, so we can pull some repository and immediately work on it :)

gremo commented 1 week ago

Yes @smnandre it's ok to provide a container for running the example or you do by your own?

smnandre commented 1 week ago

A small repository with minimal install would be ideal :)

See