Why does flutter callback work for Material Button, but not for TextFormField?

Viewed 25

I am trying to get callback to work for account registration to get data from children classes to the parent class. Here is the parent.

class SignUpPageTextFieldsAndLabels extends StatefulWidget {
  const SignUpPageTextFieldsAndLabels({Key? key}) : super(key: key);

  @override
  _SignUpPageTextFieldsAndLabels createState() => _SignUpPageTextFieldsAndLabels();
}

//Contains all the major Widgets for SignUpPage
class _SignUpPageTextFieldsAndLabels extends State<SignUpPageTextFieldsAndLabels>{
  String _firstName = '';
  String _surname = '';
  String _password = '';
  String _email = '';
  String _cellNumber = '';

  List _GetDataFields(){
    List fields = List.filled(SIGN_UP_PAGE_NUM_DATA_FIELDS, '');

    fields[FIRST_NAME] = _firstName;
    fields[SURNAME] = _surname;
    fields[PASSWORD] = _password;
    fields[EMAIL] = _email;
    fields[CELL_NUMBER] = _cellNumber;

    return fields;
  }

  @override Widget build(BuildContext context){
    return Padding(
      padding: EdgeInsetsDirectional.fromSTEB(30, 0, 30, 0),
      child: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          const CustomBackButton(),
          const ThePatriotLogo(),
          const _SignUpLabelArea(),
          EntryPageTextFormField(callback: (value) => setState(() {_firstName = value;}), 'First Name', Icons.clear),
          EntryPageTextFormField(callback: (value) => setState(() {_surname = value;}), 'Surname', Icons.clear),
          EntryPageTextFormField(callback: (value) => setState(() {_cellNumber = value;}), 'Cellphone Number', Icons.clear),
          EntryPageTextFormField(callback: (value) => setState(() {_email = value;}), 'Email', Icons.clear),
          EntryPagePasswordTextFormField(callback: (value) => setState(() {_password = value;}), 'Password'),
          EntryPagePasswordTextFormField(callback: (value) => setState(() {_password = value;}), 'Confirm Password'),
          _SignUpPageUploadPhotoButton(),
          _SignUpCreateAccountIconButton(_GetDataFields()),
        ],
      ),
    );
  }
}

Now, this is the child class that I need to work:

class EntryPageTextFormField extends StatelessWidget {
  EntryPageTextFormField(this._title, this._buttonIcon, {Key? key, required this.callback});

  final Function(String) callback;

  final _fieldTextController = TextEditingController();

  final _title;
  final _buttonIcon;

  var value = '';

  @override
  Widget build(BuildContext context){
    return Padding(
      padding: const EdgeInsetsDirectional.fromSTEB(0, 0, 0, 20),
      child: TextFormField(
        controller: _fieldTextController,
        autofocus: true,
        obscureText: false,
        decoration: const ButtonDecoration().GetButtonDecoration(_title, _buttonIcon),
        textAlign: TextAlign.start,
        keyboardType: TextInputType.emailAddress,
        onChanged: (value) {
          value = _fieldTextController.text;
          ()=>callback(_fieldTextController.text);
        }
      ),
    );
  }
}

Now, if I print the results that get passed to _SignUpCreateAccountIconButton(_GetDataFields()) they're just empty strings. However, if I change the child class's TextFormField to

      child: MaterialButton(
          child: Text("Text"),
          onPressed:()=>callback("hellow"),
      ),

If I do this, all the fields print "hellow". What is the difference that is causing this?

1 Answers

Your syntax for calling the callback function is incorrect. The shorthand notation of () => is declaring a function, not actually calling. It works in your MaterialButton example because onPressed takes a function as the input. Also, the first line setting value to _fieldTextController.text is unnecessary and so is the usage of the controller since the onChanged function passes you the current field's text.

Here's what you need:

onChanged: (text) {
    callback(text);
}

Or even more compact as recommended by @pskink:

onChanged: callback,
Related