Search code examples
flutterflutter-webflutter-reactive-forms

How to use reactive_forms ReactiveFormArray in flutter?


I was trying to create dynamic array of fields in flutter, reactive_forms was best choice. But there is no documentation for ReactiveFormArray which i need to use.

Did some trial and error and found the way to use it. Below is the answer.


Solution

  • Since there is no documentation i could find. Sharing so it may be useful for someone.

    1.Create a reactive form with FormArray

    You can also add a formgroup in the formarray if you need it by default.

        final form = FormGroup({
            'itemName': FormControl(value: ''),
            'prices': FormArray([]),
          });
    

    2.Get the FormArray We will use this list to add multiple form groups dynamically.

        FormArray get pricesList => form.control('prices') as FormArray;
    

    3.Initiate data in init method Dynamically adding a form array data.

        @override
          void initState() {
            pricesList.add(FormGroup({
              'greaterThan': FormControl<int>(value: 0),
              'lessThan': FormControl<int>(value: 10),
              'price': FormControl<int>(value: 0),
            }));
            super.initState();
          }
    
    1. Add in ReactiveForm return the form to your widget
        ReactiveForm(
                      formGroup: this.form,
                      child: Column(
                        children: <Widget>[
                          ReactiveTextField(
                            formControlName: 'itemName',
                            decoration: InputDecoration(
                              labelText: 'Item Name',
                            ),
                          ),
                          ReactiveFormArray(
                              formArrayName: 'prices',
                              builder: (context, formArray, child) {
                                final cities = pricesList.controls
                                    .map((control) => control as FormGroup)
                                    .map((currentform) {
                                  return ReactiveForm(
                                      formGroup: currentform,
                                      child: Column(
                                        children: <Widget>[
                                          ReactiveTextField(
                                            formControlName: 'greaterThan',
                                            decoration: InputDecoration(
                                              labelText: 'greater than',
                                            ),
                                          ),
                                          ReactiveTextField(
                                            formControlName: 'lessThan',
                                            decoration: InputDecoration(
                                              labelText: 'less than',
                                            ),
                                          ),
                                          ReactiveTextField(
                                            formControlName: 'price',
                                            decoration: InputDecoration(
                                              labelText: 'Price',
                                            ),
                                          ),
                                        ],
                                      ));
                                });
                                return Wrap(
                                  runSpacing: 20,
                                  children: cities.toList(),
                                );
                              }),
                          ReactiveFormConsumer(
                            builder: (context, form, child) {
                              return RaisedButton(
                                child: Text('Submit'),
                                onPressed: form.valid ? _onSubmit : null,
                              );
                            },
                          ),
                        ],
                      ),
                    ),
                  ));
    
    1. Dynamically add in Form array when you call this method, dynamically more formarray fields will be added
        addFormArray() async {
            pricesList.add(FormGroup({
              'greaterThan': FormControl<int>(value: 10),
              'lessThan': FormControl<int>(value: 50),
              'price': FormControl<int>(value: 0),
            }));
            setState(() {});
          }
    

    Simply call this method on a button click or wherever you need.