Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LiveComponent] Fix issue with onUpdated not triggered on nested array proprety #2013

Open
wants to merge 4 commits into
base: 2.x
Choose a base branch
from

Conversation

TheDutchScorpion
Copy link
Contributor

@TheDutchScorpion TheDutchScorpion commented Jul 30, 2024

Q A
Bug fix? no
New feature? yes
Issues
License MIT

When modifying a array property the onUpdated hook is only triggered when the exact key is specified.

#[LiveProp(writable: true, onUpdated: [‘firstname’ => ‘onUpdated’, ‘lastname’ => ‘onUpdated’]]

This PR will add the ability to use wildcards within the key.

#[LiveProp(writable: true, onUpdated: [‘*’ => ‘onUpdated’]]

Or

#[LiveProp(writable: true, onUpdated: [‘values.*’ => ‘onUpdated’]]

@smnandre
Copy link
Member

Hi @TheDutchScorpion: thanks for this PR.

Could you add some test here?

(especially one with something that did not work before and now would work?)

Comment on lines 665 to 668
if (LiveProp::IDENTITY === $propName) {
if (!$dehydratedUpdatedProps->hasPropValue($frontendName)) {
if (!$dehydratedUpdatedProps->hasPropValue($frontendName)
&& !$dehydratedUpdatedProps->hasNestedPathsForProperty($frontendName)) {
continue;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is the right place... for a LiveProp IDENTITY the only thing that can change is... the prop itself no ? Is this not something we should do line 680+ ?

Copy link
Contributor Author

@TheDutchScorpion TheDutchScorpion Jul 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think thats the best place either to check if there are changes to a array property. My intention was to tigger the onUpdated whenever there is a change within the array without providing a specific nested path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm wrong, but it's also strange that if the $propMetadata->onUpdated() is a string, the update hook only triggers if the property has been completely changed to another property and not if part of it has been modified.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that, but i fear doing so here will have side effects .. wdyt ?

@smnandre
Copy link
Member

smnandre commented Aug 2, 2024

I just saw you changed a bit your PR :)

Could you update your first message with a basic case scenario, describing what you wanted todo, what did not work and what will after your PR ?

It's easier for everyone to review and understand the PR :)

@kevinmade
Copy link

kevinmade commented Nov 5, 2024

Could this branch be reviewed and merged?

@kevinmade
Copy link

@smnandre

@smnandre
Copy link
Member

I'd like to get the real use case behind this, as i don't see right now how a map can be mapped to a form (without it being a collection)

Then i'd like to see is before/after for

  • basic list of scalars (ints, strings)
  • nested arrays
  • free map (like this one)
  • collection of objects

I think we need to restrict this syntax to "*" => "method", or that does not make a lot of sense to me.

At core, this is a callback when a props is updated, triggered because the value will change. That does not feels logical to call multiple times the same function.

Other comments regarding code :)

$this->ensureOnUpdatedMethodExists($component, $funcName);
$propertyOldValue = $dehydratedOriginalProps->getPropValue($key);
$component->{$funcName}($propertyOldValue);
foreach ($fullPaths as $fullPath) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop concern one callback for a prop. It should not be called multiple times. I this you could "just" replace the prevous "hasPropValue" to some "matchPropValue" or something like this and let the rest flow.

Comment on lines +692 to +693
$this->ensureOnUpdatedMethodExists($component, $funcName);
$propertyOldValue = $dehydratedOriginalProps->getPropValue($fullPath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not compute this every loop

foreach ($fullPaths as $fullPath) {
$this->ensureOnUpdatedMethodExists($component, $funcName);
$propertyOldValue = $dehydratedOriginalProps->getPropValue($fullPath);
$component->{$funcName}($propertyOldValue);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the receiving callable as no way to get what is "old value". If a "*" is used, we should pass the full prop

@@ -113,6 +113,13 @@ public function getNestedPathsForProperty(string $prop): array
return $nestedPaths;
}

public function searchFullPathsForProperty(string $prop): array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some tests if possible (with failing / problematic cases, not just happy path)

if (!$dehydratedUpdatedProps->hasPropValue($key)) {
continue;
}
$fullPaths = $dehydratedUpdatedProps->searchFullPathsForProperty($key);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do this only under conditions, and keep previous code if no "*"

@smnandre smnandre added Status: Needs Work Additional work is needed and removed Status: Needs Review Needs to be reviewed labels Nov 12, 2024
@smnandre
Copy link
Member

Upon rereading my message, I realize it came across more strongly than I intended—apologies for that. Sorry as well for the delayed response, and thank you for your contribution @TheDutchScorpion and for the poke @kevinmade

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
LiveComponent Status: Needs Work Additional work is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants