Add failing test for array update hooks $value
#8235
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds a failing test for handling of update hooks for array properties (and possibly others).
The test is structured the way that V2 handles update hooks for arrays.
See discussions #7101 and #6665.
The Scenario
When properties are updated on the front end, Livewire triggers
updatingProperty
andupdatedProperty
hooks on the backend (plus updating/ updated but they aren't needed for this example).This allows developers to hook into the updates and perform other actions or side effects based on the values in the update hooks.
In particular, the
updatingProperty
hook allows your to inspect the new property value before the property has been updated.When using hooks in V2, the
$value
passed into the hook was always the new value that a property is going to be set to and there was no$key
passed in.For example if an array gets updated by the front end (such as when using entangle), then that value is passed to the update hooks as the
$value
prop.So if you had a property with an array
['one', 'two', 'three', 'four']
and it gets changed on the front end, to['two', 'three']
, then the new value would be sent to the backend and the$value
prop on the update hooks would contain['two', 'three']
.It is to be noted that each of the updatingProperty/updatedProperty hooks would only be called once each for a single property change.
See below screen capture of this in action in V2.
The Problem
The problem is that in V3 the way the front end handles updating properties has changed.
Instead of sending the new value of a property to the backend, Livewire will now calculate the changes (diff) to a property (particularly when they are arrays/objects) and send each of the diffs as individual update calls.
What this means, is that for every update that happens to a property, each of the updating/updated hooks will be called.
In the screenshot above, this means for the
items
propertyupdatingItems
andupdatedItems
hooks will each be called 4 times.Each time the update hooks are called the
$value
that is being passed in is the values in each of the updates, so for the first hooks call it's"two"
, then second is"three"
, and then"__rm__"
and then"__rm__"
. And the$key
is now populated with the corresponding index of the update1
, then2
, then3
, then4
.For users that were relying on this functionality in V2 this is an unexpected change.
It also means the internal
__rm__
value is being exposed, meaning a developer has to interact with it and decide what to do with it, which is not ideal.See below screen capture of this in action in V3.
Solutions
Solution A) Change the front end
We could go back to how the front end handles a property update when it gets sent to the server like in V2.
Pros
Cons
Solution B) Only use the diff to determine if a request should be sent, but use the whole value for the update
This depends on the reasoning for the diff in the first place. My suspicion is that calculating the diffs is helpful for determining whether a request should even be sent at all. But we could still do that for handling of the request, but then send the new value as a single update call (not push the diff into the updates).
Pros
Cons
Solution C) Aggregate the changes on the backend
We could group all the changes for a particular property together on the backend and make the update to the property with the final value of the property - thus calling the update hooks once with the final value.
Pros
Cons
Solution D) Do nothing
These changes have been in effect for a while now. So we could just leave it the way it is.
Pros
Cons
__rm__
is still exposed to the developer.Recomendation
I think if I were to choose, I would probably lean towards solution B, as it could be the best of both worlds. I hold this opinion loosly though as I don't have the full context on why diffs are good.