ux
ux copied to clipboard
[Live] Use (de)hydration system for event payload
Hi!
2 times recently, the same situation has occurred with users - where they want to emit an event with an object - e.g.
#[LiveAction]
public function save(LiveResponder $responder): void {
$responder->emitUp('foo:save', [
// dto
'data' => new BlogPost($id, $title),
// or an entity
'post' => $post,
]);
}
And the listener:
#[LiveListener('foo:save')]
public function saveMandatoryDataSection(#[LiveArg] BlogPost $data, #[LiveArg] Post $post): void
{
}
Currently, this doesn't work and it wasn't designed to work. Arrays are JSON-encoded, and all other values are just printed in the attributes for the frontend - https://github.com/symfony/ux/blob/2.x/src/LiveComponent/src/Util/LiveAttributesCollection.php#L33-L39 - objects were not designed to work here.
But... it could work. What if we sent the individual values (at least the values that are objects) through the dehydration system? Then, we registered a "value resolver" that only acted for LiveListener
situations that would attempt to hydrate these values?
Or perhaps this is something you can opt into?
Or perhaps we just need better docs that say:
- If you want to pass an entity, pass
'post' => $post->getId()
and then the normal entity value resolve will allow for aPost $post
argument. - If you want to pass a DTO, send it through the deserializer, then unserialize it in your live listener method.
Solution 2 clearly for me.
Or users will expose a lot of data not knowing this is "public"
I'm for solution 1. What data are you talking about @smnandre? It's gonna be the same data already dehydrated by the LiveComponent?
By "solution 2" i mean "better doc" to be clear :)
And to be honest passing full object in Events is like passing full object in Messenger messages.... not something i'd recommand.
It would be nice to allow passing object as explained in my issue some times ago: https://github.com/symfony/ux/issues/1483. It's not that bad to allow components to talk each other using small dto's, the same way that components "talkt" to javascript with the hydrate/dehydrate.
You mean the issue i suggested a working solution ? :p