TextFormField validator not working - The method 'validate' was called on null

40,930

Solution 1

You didn't add the key to the form, this code should work:

class _LoginForm extends State<LoginForm> {
  // GlobalKey<FormState> formKey = GlobalKey();
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  String _email;
  String _password;

  void validateAndSave() {
    final FormState form = _formKey.currentState;
    if (form.validate()) {
      print('Form is valid');
    } else {
      print('Form is invalid');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(left: 15.0, right: 15.0),
      child: Form(
        key: _formKey,
        child: Column(
          // mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            SizedBox(
              height: 150.0,
            ),
            // input field for email
            TextFormField(
              decoration: InputDecoration(labelText: 'Email'),
              validator: (value) =>
                  value.isEmpty ? 'Email cannot be blank' : null,
              // onSaved: (value) => _email = value,
            ),
            // input field for password
            TextFormField(
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
              validator: (value) =>
                  value.isEmpty ? 'Password cannot be blank' : null,
              // onSaved: (value) => _password = value,
            ),
            RaisedButton(
              child: Text(
                'Login',
                style: TextStyle(fontSize: 20.0),
              ),
              onPressed: validateAndSave,
            ),
          ],
        ),
      ),
    );
  }
}

Solution 2

If someone have the same error even adding the key and your structure is:

Form => ListView => [TextFormField(s)], 

try to change the structure:

Form => SingleScrollView => Column

This change worked for me.

Happy coding.

Solution 3

The question was already solved, but if it's still not working after adding the key and changing the structure to one of the following:

Form => SingleChildScrollView => Column => [TextFormField(s)],

or

SingleChildScrollView => Form => Column => [TextFormField(s)],

Try adding:

autovalidateMode: AutovalidateMode.onUserInteraction

For example:

TextFormField(
  decoration: const InputDecoration(
    icon: Icon(Icons.person),
    labelText: 'User:',
  ),
  onSaved: (){},
  autovalidateMode:
      AutovalidateMode.onUserInteraction,
  validator: (value) {
    if (value == null || value.isEmpty) {
      return 'Please enter your user name.';
    } else if (value.contains('@')) {
      return 'Please don\'t use the @ char.';
    }
    return null;
  },
  textInputAction: TextInputAction.next,
),
Share:
40,930
Santhosh Jose
Author by

Santhosh Jose

Specialties Bacon Number: 3 Experienced at Loading and Un-loading....weights.

Updated on July 05, 2022

Comments

  • Santhosh Jose
    Santhosh Jose almost 2 years

    I am trying to build a simple login page for a new flutter app. The widget tree is very basic. It consists of a MaterialApp that contains a Scaffold. The 'home' of the Scaffold is a StatefulWidget which contains the Form with two TextFormFields inside.

    The TextFormFields have 'validator' code to check for null values.

    There is a button which invokes a method 'validateAndSave' when pressed. Inside this method, I am calling 'validate' method for an instance of the GlobalKey.

    When clicking on the button, the validators don't seem to be firing and I am getting the following error message:

    I/flutter (10459): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
    I/flutter (10459): The following NoSuchMethodError was thrown while handling a gesture:
    I/flutter (10459): The method 'validate' was called on null.
    I/flutter (10459): Receiver: null
    I/flutter (10459): Tried calling: validate()
    I/flutter (10459): 
    I/flutter (10459): When the exception was thrown, this was the stack:
    I/flutter (10459): #0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
    I/flutter (10459): #1      _LoginForm.validateAndSave (package:playground/main.dart:33:13)
    

    I tried running flutter clean on the project and re-running the application. I still get the error message.

    Here is the code that I am running.

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Playground',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: Scaffold(body:LoginForm()
          ),
        );
      }
    }
    
    class LoginForm extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => _LoginForm();
    }
    
    class _LoginForm extends State<LoginForm>{
      // GlobalKey<FormState> formKey = new GlobalKey();
      final _formKey = new GlobalKey<FormState>();
      String _email;
      String _password;
    
      void validateAndSave(){
        final form = _formKey.currentState;
        if(form.validate())
        {
          print ('Form is valid');
        }
        else
        {
          print('form is invalid');
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
            padding: EdgeInsets.only(left: 15.0, right: 15.0),
            child: Form(
                child: Column(
                  // mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: <Widget>[
                      SizedBox(height: 150.0,),
                      //input field for email
                      TextFormField(
                        decoration: InputDecoration(labelText: 'Email'),
                        validator: (value) => value.isEmpty ? 'Email cannot be blank':null,
                        //       onSaved: (value) => _email = value,
                      ),
                      //input field for password
                      TextFormField(
                        decoration: InputDecoration(labelText: 'Password'),
                        obscureText: true,
                        validator: (value) => value.isEmpty ? 'Password cannot be blank':null,
                        //     onSaved: (value) => _password = value,
                      ),
                      RaisedButton(
                        child: Text ('Login', style: TextStyle(fontSize: 20.0),),
                        onPressed: validateAndSave,
                      )
                    ]
                )
            )
        );
      }
    }
    

    I feel like I have missed something in the code. I would appreciate any help in sorting this issue out.

  • Fellow7000
    Fellow7000 over 3 years
    Thanks a lot! This saved a lot of time today! :)
  • Eradicatore
    Eradicatore about 3 years
    This is an awesome example of how to validate AFTER you click submit, so it doesn't show red while you type in the email.
  • Soorya
    Soorya almost 3 years
    @Pedro Molina can you give more explanation why this is happening?