NoSuchMethodError: The method 'validate' was called on null

Viewed 16879

Im a beginer in Flutter and here is the problem- im trying to build a form with validation and 'Submit' button which must navigate to a new screen but there is 'NoSuchMethodError: The method 'validate' was called on null' in debuger when i press this button . Here is the code:

class _SignInPage extends State<SignInPage> {
  final scaffoldKey = GlobalKey<ScaffoldState>();
  final formKey = GlobalKey<FormState>();

  String _email;
  String _password;

  void _submit() {
    final form = formKey.currentState;

    if (form.validate()) {
      form.save();
      _performLogin();
    }
  }

  void _performLogin() {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => ConnectPage()),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      body: new Container(
          margin: new EdgeInsets.symmetric(vertical: 200.0, horizontal: 35.0),
          padding: EdgeInsets.all(20.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            key: formKey,
            children: [
              TextFormField(
                keyboardType: TextInputType.emailAddress,
                autofocus: false,
                decoration: InputDecoration(
                    contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    labelText: 'Email'),
                validator: (val) =>
                    !val.contains('@') ? 'Not a valid email.' : null,
                onSaved: (val) => _email = val,
              ),
              TextFormField(
                autofocus: false,
                obscureText: true,
                decoration: InputDecoration(
                    hintText: 'Password',
                    contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20.0)),
                    labelText: 'Password'),
                validator: (val) =>
                    val.length < 6 ? 'Password too short.' : null,
                onSaved: (val) => _password = val,
              ),
              Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
                new Row(children: [
                  FlatButton(
                    child:
                        Text('Sign Up', style: TextStyle(color: Colors.black)),
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(builder: (context) => SignUpPage()),
                      );
                    },
                  ),
                  FlatButton(
                    child:
                        Text('Sign In', style: TextStyle(color: Colors.black)),
                    onPressed: () {
                      // Navigate to second screen when tapped!
                    },
                  ),
                ]),
                new Row(children: [
                  Radio(
                    activeColor: Colors.blue,
                    value: Colors.grey,
                    onChanged: (activeColor) {},
                  ),
                  Text(
                    "Keep me signed in",
                    style: new TextStyle(color: Colors.black),
                  )
                ])
              ]),
              RaisedButton(
                color: Colors.blue,
                onPressed: _submit,
                child: new Text('Sign in'),
              ),
            ],
          )),
    );
  }
}
  1. How can i fix that?
  2. How to add space between two forms?
7 Answers

You have to wrap your TextFormFields with the Form widget.

As per docs,

Each individual form field should be wrapped in a FormField widget, with the Form widget as a common ancestor of all of those*.

This error occures when:

  1. Form contains only one TextFormField
  2. You didn't bind key to Form
  3. Some widgets in your Form are not wrapped with FormField widget

In my case i forgot the key parameter of Form.

Try to wrap your TextFieldField in Form widget and also put key parameter. You might want to check out TextField and errorText property.

You may miss:

final _formKey = GlobalKey<FormState>(); 

key: _formKey,

    final _formKey = GlobalKey<FormState>();

    @override
    Widget build(BuildContext context) {
      return Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextFormField(
              decoration: const InputDecoration(
                hintText: 'Enter your email',
              ),
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 16.0),
              child: RaisedButton(
                onPressed: () {
                  // Validate will return true if the form is valid, or false if
                  // the form is invalid.
                  if (_formKey.currentState.validate()) {
                    // Process data.
                  }
                },
                child: Text('Submit'),
              ),
            ),
          ],
        ),
      );
    }

Try to wrap your TextFieldField in Form widget and also put key parameter.

final _formKey = GlobalKey<FormState>(); 

Example code:

  Form(
    key: _formKey,
    child: TextFormField(
          decoration: const InputDecoration(
            hintText: 'Enter your email',
          ),
          validator: (value) {
            if (value.isEmpty) {
              return 'Please enter some text';
            }
            return null;
          },
        ),
     ),

Note: In is case, please ensure key value

In my case you forgot the key parameter of Form.

final _formKey = GlobalKey<FormState>();
Form(
 key: _formKey,);
Related