title: Generate TextEditingController for dynamicly generated TextFormField in Flutter
body: <p>I have to generate <code>TextFormField</code> under a <code>Form</code> widget based on an array return from the API. Once these fields are generated the can enter values in it. When the user clicks on the submit button, the values of each field should be put in an array to post the API.</p>
  <p><strong>Object to be sent to API</strong></p>
  <pre><code>{
     &quot;billerId&quot; :&quot;12341249&quot;,
     &quot;customerParams&quot;: [ // Each object in this array denotes input field's name and value
         {
            &quot;name&quot;: &quot;Consumer Number&quot;,
            &quot;value&quot; : &quot;43141&quot;
         },
         {
            &quot;name&quot;: &quot;Subdivision Code&quot;,
            &quot;value&quot;: &quot;23&quot;
         }
      ]
  }
  </code></pre>
  <p>Below is my <code>StatefulWidget</code> where I'm looping the over <code>fields</code> array (which came from API) to generate fields. My problem is when I'm hitting the <strong>Submit</strong> button, the print statement logs the object, similar to above, but the last field pushed twice.</p>
  <pre><code>// All necessary imports
  
  class AddCustomerDetails extends StatefulWidget {
    final Biller biller;
  
    const AddCustomerDetails({Key key, this.biller}) : super(key: key);
  
    @override
    _AddCustomerDetailsState createState() =&gt; _AddCustomerDetailsState();
  }
  
  class _AddCustomerDetailsState extends State&lt;AddCustomerDetails&gt; {
    final _formKey = GlobalKey&lt;FormState&gt;();
    List _customerInputFields;
    var _submitObj;
  
    @override
    void initState() {
      _customerInputFields = widget.biller.customerParameter;
      _submitObj = {'billerId': widget.biller.id, 'customerParams': []}; // Initializing it here
      super.initState();
    }
  
    Widget _generateForm(List fields) {
      return Form(
        key: _formKey,
        child: Column(
          children: [
            ...fields.map((field) {
              return TextFormField(
                validator: (value) =&gt; _validateField(value),
                onChanged: (value) {
                  _submitObj['customerParams']
                      .add({'name': field['paramName'], 'value': value}); // I know this is wrong and will push object on every key press
                },
              );
            }).toList(),
            SizedBox(height: 16),
            RaisedButton(
              onPressed: () {
                if (_formKey.currentState.validate()) {
                  print(_submitObj); // See Actual response in snippet below
                }
              },
              child: Text('Submit'),
            ),
          ],
        ),
      );
    }
  
    String _validateField(value) {
      // ... Validate field if empty
    }
  
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        body: Column(
          children: [
            Padding(
              padding: EdgeInsets.all(
                AppMediaQuery(context).appHorizontalPadding(4),
              ),
              child: _generateForm(_customerInputFields),
            ),
          ],
        ),
      );
    }
  }
  
  </code></pre>
  <p><strong>Actual response</strong></p>
  <pre><code>I/flutter ( 8118): {billerId: JBVNL0000JHA01, customerParams: [{name: Consumer Number, value: 4}, {name: Consumer Number, value: 43}, {name: Consumer Number, value: 431}, {name: Consumer Number, value: 4314}, {name: Consumer Number, value: 43141}, {name: Subdivision Code, value: 2}, {name: Subdivision Code, value: 23}]}
  </code></pre>
  <p><strong>I don't want it to push the object every time I press the key.</strong>
  How this can be achieved? Of course, I can add a denounce, but that won't solve the problem.</p>