[2.x] Resolve Closure before checking if a prop implements the Arrayable contract #706
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.
On my projects, I use
spatie/laravel-view-models
to organize complex controller responses.The
Spatie\ViewModels\ViewModel
implements theIlluminate\Contracts\Support\Arrayable
, so when Inertia can handle aViewModel
instance like a set of props.When a
ViewModel
instance is converted to an array, all public properties and methods are converted to array keys. If a public method does not expect any parameters, then it is executed and its value is used. On the other hand, if a public method expects one or more parameters, it is converted to a\Closure
.Currently, the
Inertia\Response@resolveArrayableProperties()
method, checks if a property is a\Closure
after checking if it is an object that implementsIlluminate\Contracts\Support\Arrayable
, which to me makes little sense as the method is named to "resolve arrayable properties".Use case
I have the following view model:
Where
App\Support\UserPreferences
also implementsIlluminate\Contracts\Support\Arrayable
.Currently, when
SettingsViewModel@toArray()
is called,SettingsViewModel@preferences
is converted to a\Closure
, and whenInertia\Response@resolveArrayableProperties()
is called, the\Closure
is executed after checking if the property implements theArrayable
contract.I end up with a property holding an empty object, as it doesn't get properly processed.
A simpler example would be returning a
\Closure
that returns a simpleArrayable
instance:The response currently converts the
foo
property to an empty object, when I, as a user, would expect itstoArray()
method to be executed:This PR:
\Closure
before checking if a property implementsArrayable