Flutter onChanged: not triggering method to read textfield content

Viewed 930

I have a form where users capture information on multiple textfields. Within the Onchange:, I can see that there's activity every time the user types something on the textfield. However, when I call a method to read the textfield content, the method is not being fired. For example, I call the updateFirstName() method within the OnChange: within the nameController textfield. The method doesn't fire and the App fails when I press Save because the FirstName field is null. Any reason why the updateFirstName method on my code below is not being called? I'm new to Flutter so I might be missing something basic.

import 'dart:ffi';
import 'package:flutter/material.dart';
import '../widgets/main_drawer.dart';
import '../utils/database_helper.dart';
import '../models/customer.dart';
import 'package:intl/intl.dart';

class CustomerDetailsScreen extends StatefulWidget {
  static const routeName = '/customer-details';

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

class _CustomerDetailsScreenState extends State<CustomerDetailsScreen> {
  //Define editing controllers for all the text fields
  TextEditingController nameController = TextEditingController();
  TextEditingController surnameController = TextEditingController();
  TextEditingController cellphoneController = TextEditingController();
  TextEditingController emailController = TextEditingController();

  //Connecting to the database
  DatabaseHelper helper = DatabaseHelper();

  //Define some variables
  String appBarTitle;
  Customer customer; //This is the Customer Model

  /*
  String sFirstName;
  String sSurname;
  String sCellNumber;
  String sEmailAddress;
  String sCompanyName = '-';
*/

  var _formKey = GlobalKey<FormState>();

  //Method to validate e-mail address
  bool validateEmail(String value) {
    Pattern pattern =
        r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
    RegExp regex = new RegExp(pattern);
    return (!regex.hasMatch(value)) ? false : true;
  }

  @override
  Widget build(BuildContext context) {
    TextStyle textStyle = Theme.of(context).textTheme.title;

    //Populate the text fields
    //nameController.text = customer.sFirstName;
    //surnameController.text = customer.sSurname;
    //cellphoneController.text = customer.sCellNumber;
    //emailController.text = customer.sEmailAddress;

    return Scaffold(
      appBar: AppBar(
        title: Text('Edit Customer'),
      ),
      body: GestureDetector(
        //Gesture detector wrapped the entire body so we can hide keyboard \
        // when user clicks anywhere on the screen
        behavior: HitTestBehavior.opaque,
        onTap: () {
          FocusScope.of(context).requestFocus(new FocusNode());
        },
        child: Form(
          key: _formKey,
          child: Padding(
            padding: EdgeInsets.only(top: 15.0, left: 10.0, right: 10.0),
            child: ListView(
              children: <Widget>[
                //First Element - Name
                Padding(
                  padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                  child: TextFormField(
                    controller: nameController,
                    style: textStyle,
                    textCapitalization: TextCapitalization.words,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Please enter your name';
                      }
                      return null;
                    },
                    onChanged: (value) {
                      debugPrint('Something changed on the Name Text Field');

                      updateFirstName();
                    },
                    decoration: InputDecoration(
                      labelText: 'Name',
                      labelStyle: textStyle,
                      errorStyle:
                          TextStyle(color: Colors.redAccent, fontSize: 15.0),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(5.0),
                      ),
                    ),
                  ),
                ),

                //Second Element - Surname
                Padding(
                  padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                  child: TextFormField(
                    controller: surnameController,
                    style: textStyle,
                    textCapitalization: TextCapitalization.words,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Please enter your surname';
                      }
                      return null;
                    },
                    onChanged: (value) {
                      debugPrint('Something changed on the Surname Text Field');
                      updateSurname();
                    },
                    decoration: InputDecoration(
                      labelText: 'Surname',
                      labelStyle: textStyle,
                      errorStyle:
                          TextStyle(color: Colors.redAccent, fontSize: 15.0),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(5.0),
                      ),
                    ),
                  ),
                ),

                //Third Element - Cellphone
                Padding(
                  padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                  child: TextFormField(
                    controller: cellphoneController,
                    style: textStyle,
                    keyboardType: TextInputType.number,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Please enter your cellphone number';
                      } else {
                        if (value.length < 10)
                          return 'Cell number must be at least 10 digits';
                      }
                      return null;
                    },
                    onChanged: (value) {
                      debugPrint(
                          'Something changed on the Cellphone Text Field');
                      updateCellNumber();
                    },
                    decoration: InputDecoration(
                      labelText: 'Cellphone',
                      labelStyle: textStyle,
                      errorStyle:
                          TextStyle(color: Colors.redAccent, fontSize: 15.0),
                      hintText: 'Enter Cell Number e.g. 0834567891',
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(5.0),
                      ),
                    ),
                  ),
                ),

                //Fourth Element - Email Address
                Padding(
                  padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                  child: TextFormField(
                    controller: emailController,
                    style: textStyle,
                    keyboardType: TextInputType.emailAddress,
                    validator: (String value) {
                      if (value.isEmpty) {
                        return 'Please enter your e-mail address';
                      } else {
                        //Check if email address is valid.
                        bool validmail = validateEmail(value);
                        if (!validmail) {
                          return 'Please enter a valid e-mail address';
                        }
                      }
                      return null;
                    },
                    onChanged: (value) {
                      debugPrint(
                          'Something changed on the Email Address Text Field');
                      updateEmailAddress();
                    },
                    decoration: InputDecoration(
                      labelText: 'E-mail',
                      labelStyle: textStyle,
                      errorStyle:
                          TextStyle(color: Colors.redAccent, fontSize: 15.0),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(5.0),
                      ),
                    ),
                  ),
                ),

                //Fifth Element - Row for Save Button
                Padding(
                    padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          child: RaisedButton(
                              color: Theme.of(context).primaryColorDark,
                              textColor: Theme.of(context).primaryColorLight,
                              child: Text(
                                'Save',
                                textScaleFactor: 1.5,
                              ),
                              onPressed: () {
                                setState(() {
                                  if (_formKey.currentState.validate()) {
                                    debugPrint('Save button clicked');

                                    //Call the Save method only if the validation is passed
                                    _saveCustomerDetails();
                                  }
                                });
                              }),
                        ),
                      ],
                    )),
              ],
            ),
          ),
        ),
      ),
    );
  }

  //**********************Updating what is captured by the user on each text field******************/

  //Update the sFirstName of the Customer model object
  void updateFirstName() {
    print('The updateFirstName was called');

    customer.sFirstName = nameController.text;
  }

  //Update the sSurname of the Customer model object
  void updateSurname() {
    customer.sSurname = surnameController.text;
  }

  //Update the sCellNumber of the Customer model object
  void updateCellNumber() {
    customer.sCellNumber = cellphoneController.text;
  }

  //Update the sEmailAddress of the Customer model object
  void updateEmailAddress() {
    customer.sEmailAddress = emailController.text;
    customer.sCompanyName = '-';
  }

  //**********************END - Updating what is captured by the user on each text field******************/

  //**************************Saving to the Database*************************************/

  void _saveCustomerDetails() async {
    //moveToLastScreen();

    //Update the dtUpdated of the Customer model with current time (Confirm that it is GMT)

    print('Trying to save customer info was called');

    customer.dtUpdated = DateFormat.yMMMd().format(DateTime.now());

    print('Trying to save customer info was called - 2');

    int result;

    result = await helper.insertNewHumanCustomer(customer);

    if (result != 0) {
      //Saving was a Success
      _showAlertDialog('Success', 'Customer details saved successfully');

      print('The customer details were saved successfully');
    } else {
      //Saving was a Failure

      print('FAILURE - The customer details failed to save');

      _showAlertDialog('Failure', 'Oopsy.....something went wrong. Try again');
    }
  }

  //*****Show Alert Popup message*****/
  void _showAlertDialog(String title, String message) {
    AlertDialog alertDialog = AlertDialog(
      title: Text(title),
      content: Text(message),
    );

    showDialog(context: context, builder: (_) => alertDialog);
  }
//*****END - Show Alert Popup message*****/

  //**************************Saving to the Database*************************************/

}
0 Answers
Related