Reputation: 113
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'),
),
],
)),
);
}
}
Upvotes: 11
Views: 17427
Reputation: 2839
This error occures when:
Form
contains only one TextFormField
Form
Form
are not wrapped with FormField
widgetUpvotes: 16
Reputation: 399
In my case you forgot the key parameter of Form.
final _formKey = GlobalKey<FormState>();
Form(
key: _formKey,);
Upvotes: 0
Reputation: 2490
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
Upvotes: 0
Reputation: 64
Try to wrap your TextFieldField
in Form widget and also put key parameter. You might want to check out TextField
and errorText
property.
Upvotes: 2
Reputation: 876
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'),
),
),
],
),
);
}
Upvotes: 1
Reputation: 21758
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*.
Upvotes: 32