-
Notifications
You must be signed in to change notification settings - Fork 45
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
wire:modeling checkboxes to sub-key of array adds extra ""
checked item
#896
Comments
@benborgers To avoid the extra blank entry, try initializing the
or
|
That works, thank you! Is binding to an undefined key undefined behavior in Livewire? Or is this a different code path that has a small bug? |
You're welcome @benborgers ! To the best of my understanding, if you don't initialize an array used in a In my apps, I make sure I initialize all properties used in my |
@benborgers thanks for the report! Yeah seems like a bug in how the checkbox groups are initialised. For future reference, this is what the Volt component would look like (basically the same, just one file) 😉 <?php
use Livewire\Volt\Component;
new class extends Component {
public array $notifications = [];
};
?>
<div>
<div>
@json($notifications)
<flux:checkbox.group wire:model.live="notifications.subkey" label="Notifications">
<flux:checkbox label="Push notifications" value="push" />
<flux:checkbox label="Email" value="email" />
<flux:checkbox label="In-app alerts" value="app" />
<flux:checkbox label="SMS" value="sms" />
</flux:checkbox.group>
</div>
</div> |
I've investigated this and found the issue. I've submitted a PR with a fix. Here's the PR description for anyone that is interested. The scenarioCurrently if you <?php
use Livewire\Volt\Component;
new class extends Component {
public $notifications;
};
?>
<div>
@json($notifications)
<flux:checkbox.group wire:model.live="notifications" label="Notifications">
<flux:checkbox label="Push notifications" value="push" />
<flux:checkbox label="Email" value="email" />
<flux:checkbox label="In-app alerts" value="app" />
<flux:checkbox label="SMS" value="sms" />
</flux:checkbox.group>
</div> The problemThe problem is that it is never being initialised to an empty array like it should be. Instead internally it's state is being initialised to an empty string. So then when a new item is added, we check to see if it currently is an array, and if not call getState() {
return this.options().multiple ? Array.from(this.state) : this.state
} The solutionThe reason it was never being initialised to an empty array is because there was a check for if (value === null) value = this.options().multiple ? [] : '' So this PR fixes that. The bonus scenarioBut there is also an issue where if the property is not initialised, for example if you are binding to a key in array that doesn't yet exist, like <?php
use Livewire\Volt\Component;
new class extends Component {
public $settings = [];
};
?>
<div>
@json($settings)
<flux:checkbox.group wire:model.live="settings.notifications" label="Notifications">
<flux:checkbox label="Push notifications" value="push" />
<flux:checkbox label="Email" value="email" />
<flux:checkbox label="In-app alerts" value="app" />
<flux:checkbox label="SMS" value="sms" />
</flux:checkbox.group>
</div> The bonus problemThis is what was originally reported and what I started investigating, which sent me to the depths of the Alpine/Livewire/Flux divide, and also discovered the first problem above. What is happening in this scenario, is that when // If nested model key is undefined, set the default value to empty string. Meaning that Now when the SelectableGroup is then initialising, to make sure that the value is first an array (same line as the issue above), it's failing the if (value === null) value = this.options().multiple ? [] : '' The bonus solutionSo the solution is to update the check for both null and empty string values, and now everything works happily. if (value === null || value === '') value = this.options().multiple ? [] : '' Side noteNormally I wouldn't put two fixes together in the same PR, but I believe this warrants it due to the intricate and similar nature of it, meant it's easier to just explain it all in one 😁 I can split though if you'd prefer. The solution fixes #812 The bonus solution fixes #896 |
Flux version
v1.1.0
Livewire version
v3.5.17
What is the problem?
When a set of Flux checkboxes wire:modeled to
someProperty.subkey
, the first item in the array is""
.For example:
["", "first_selection", "second_selection"]
. When nothing is selected, it's[""]
.2024-12-19.at.12.32.29.mp4
Code snippets
(not Volt, sorry!)
How do you expect it to work?
If zero checkboxes are checked, the array's length should be 0; if 1 checkbox is checked, the array's length should be 1; etc.
Please confirm (incomplete submissions will not be addressed)
The text was updated successfully, but these errors were encountered: