title: Why must I call didChange inside onChanged (in Flutter)?
body: <p>I am trying to use a <code>DropdownButton</code> within a <code>Form</code> to update a database record but unless I call <code>didChange</code> inside the <code>onChanged</code> callback the value written to the database is <code>null</code> instead of the value selected from the <code>DropdownMenu</code>.</p>
  
  <p>From <a href="https://api.flutter.dev/flutter/widgets/FormFieldState/didChange.html" rel="nofollow noreferrer">the documentation</a>, the purpose of <code>didChange</code> is to trigger <code>onChanged</code>, so it doesn't seem to make any sense to have to call it from INSIDE <code>onChanged</code>. But if I don't, the code doesn't work.</p>
  
  <p>See:</p>
  
  <pre><code>import 'package:flutter/material.dart';
  
  void main() =&gt; runApp(MinimalReproducibleExample());
  
  class MinimalReproducibleExample extends StatefulWidget {
    @override
    _MinimalReproducibleExampleState createState() =&gt; _MinimalReproducibleExampleState();
  }
  
  class _MinimalReproducibleExampleState extends State&lt;MinimalReproducibleExample&gt; {
    Enquiry _newEnquiry = Enquiry();
    GlobalKey&lt;FormState&gt; _formKey = GlobalKey&lt;FormState&gt;();
    String _selectedAgent = '';
    String _selectedManager = '';
    @override
    Widget build(context) {
      return MaterialApp(
        home: Scaffold(
          body: Form(
            key: _formKey,
            child: Column(
              children: [
                FormField(
                  builder: (state) {
                    return DropdownButton(
                      items: ['', 'A'].map((val) =&gt; DropdownMenuItem&lt;String&gt;(child: Text(val), value: val)).toList(),
                      value: _selectedAgent,
                      onChanged: (val) =&gt; setState(() {
                        _selectedAgent = val;
                        // state.didChange(val);
                      }),
                    );
                  },
                  onSaved: (val) =&gt; _newEnquiry.agent = val,
                ),
                FormField(
                  builder: (state) {
                    return DropdownButton(
                      items: ['', '1'].map((val) =&gt; DropdownMenuItem&lt;String&gt;(child: Text(val), value: val)).toList(),
                      value: _selectedManager,
                      onChanged: (val) =&gt; setState(() {
                        _selectedManager = val;
                        state.didChange(val);
                      }),
                    );
                  },
                  onSaved: (val) =&gt; _newEnquiry.manager = val,
                ),
                RaisedButton(
                  onPressed: () {
                    _formKey.currentState.save();
                    print(_newEnquiry.agent);
                    print(_newEnquiry.manager);
                  },
                ),
              ],
            ),
          ),
        ),
      );
    }
  }
  
  class Enquiry {
    String agent;
    String manager;
    Enquiry({this.agent, this.manager});
  }
  </code></pre>
  
  <p>Running the code above (in Chrome, in case the device makes a difference) results in: "<code>null</code> 1" being printed. But when you un-comment the commented line the result is "A 1".</p>
  
  <p>Why is it necessary? Or what am I doing wrong?</p>