Description
Hi,
Firstly, thanks for this library. Its amazing for dealing with forms and saves a lot of time!
I am currently using it to create/edit events, with the following fields
- Name
- Description
- Date
- Start Time
- Pricing [] (list of formgroups)
- Category (text field with typeahead)
- Price (text field with int type)
Defined as so:
var form = FormGroup({
"name": FormControl<String>(value: "", validators: [Validators.required]),
"description": FormControl<String>(value: ""),
"date": FormControl<DateTime>(value: null, validators: [Validators.required]),
"time": FormControl<DateTime>(value: null, validators: [Validators.required]),
"pricing": FormArray([])
});
var pricingGroup = FormGroup({
"category": FormControl<String>(value: "", validators: [Validators.required]),
"cost": FormControl<int>(value: 0, validators: [Validators.required])
});
The issue arises when I attempt to set a value to the form, to edit an existing event.
form.value = {
"name": "Event Name",
"description": "Fake description",
"date": DateTime.now(),
"time": DateTime.now(),
"pricing": [
pricingGroup..value = {
"category": "General",
"cost": 200
}
]
};
What I'm doing is converting the json to a formgroup, for each pricing object, which i need to do to ensure that the validators are applied, or for more advanced requirements (formgroups with nested form arrays etc).
The issue arises in this code in FormArray
@override
void updateValue(
List<T?>? value, {
bool updateParent = true,
bool emitEvent = true,
}) {
for (var i = 0; i < _controls.length; i++) {
if (value == null || i < value.length) {
_controls[i].updateValue(
value?.elementAt(i),
updateParent: false,
emitEvent: emitEvent,
);
}
}
if (value != null && value.length > _controls.length) {
final newControls = value
.toList()
.asMap()
.entries
.where((entry) => entry.key >= _controls.length)
.map((entry) => FormControl<T>(value: entry.value))
.toList();
addAll(
newControls,
updateParent: updateParent,
emitEvent: emitEvent,
);
} else {
updateValueAndValidity(
updateParent: updateParent,
emitEvent: emitEvent,
);
}
}
specifically
.map((entry) => FormControl<T>(value: entry.value))
This wraps every formgroup in a formcontrol, which breaks form handling (validations and .value don't work correctly)
To resolve my issue, I've done this
final List<AbstractControl<T>> newControls = value
.toList()
.asMap()
.entries
.where((entry) => entry.key >= _controls.length)
.map((entry) {
if (entry.value is AbstractControl) {
return entry.value as AbstractControl<T>;
}
return FormControl<T>(value: entry.value);
})
.toList();
which makes everything work correctly.
Does it make sense to change the code to this?