Reputation: 83
I'm trying to add a validator to a widget:
import 'package:flutter/material.dart';
import 'package:flutter_app_1/utils/routes.dart';
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
String name = "";
bool changeButton = false;
final _formKey = GlobalKey<FormState>();
moveToHome(BuildContext context) async {
if (_formKey.currentState.validate()) {
setState(() {
changeButton = true;
});
await Future.delayed(Duration(seconds: 1));
await Navigator.pushNamed(context, MyRoutes.homeRoute);
setState(() {
changeButton = false;
});
}
}
@override
Widget build(BuildContext context) {
return Material(
color: Colors.white,
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: [
Image.asset(
"assets/images/login_image.png",
fit: BoxFit.cover,
height: 500,
),
SizedBox(
height: 20.0,
),
Text(
"Welcome $name",
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
SizedBox(
height: 28.0,
),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 16.0, horizontal: 32.0),
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
hintText: "Enter User Name",
labelText: "Username",
),
validator: (String? value) {
if (value != null && value.isEmpty) {
return "Username can't be empty";
}
return null;
},
onChanged: (value) {
name = value;
setState(() {});
},
),
TextFormField(
obscureText: true,
decoration: InputDecoration(
hintText: "Enter password",
labelText: "Password",
),
validator: (String? value) {
if (value != null && value.isEmpty) {
return "Password can't be empty";
}
return null;
},
),
SizedBox(
height: 40.0,
),
Material(
color: Colors.deepPurple,
borderRadius:
BorderRadius.circular(changeButton ? 50 : 8),
child: InkWell(
onTap: () => moveToHome(context),
child: AnimatedContainer(
duration: Duration(seconds: 1),
width: changeButton ? 50 : 150,
height: 50,
//color: Colors.deepPurple,
alignment: Alignment.center,
child: changeButton
? Icon(
Icons.done,
color: Colors.white,
)
: Text(
"Login",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18),
),
// decoration: BoxDecoration(
// //color: Colors.deepPurple,
// // shape: changeButton
// // ? BoxShape.circle
// // : BoxShape.rectangle,
// ),
),
),
),
// ElevatedButton(
// child: Text("Login"),
// style: TextButton.styleFrom(minimumSize: Size(150, 40)),
// onPressed: () {
// Navigator.pushNamed(context, MyRoutes.homeRoute);
// })
],
),
)
],
),
),
));
}
}
but I'm getting this error:
The method 'validate' can't be unconditionally invoked because the receiver can be 'null'. Try making the call conditional (using '?.') or adding a null check to the target ('!')
Upvotes: 8
Views: 28722
Reputation: 1
the correct if statement:
moveToHome(BuildContext context) async {
if (_formkey.currentState!.validate()) {
setState(() {
changeButton = true;
});
await Future.delayed(Duration(seconds: 1));
await Navigator.pushNamed(context, MyRoutes.HomeRoute);
setState(() {
changeButton = false;
});
form null safety issues:
TextFormField(
// ignore: prefer_const_constructors
decoration: InputDecoration(
hintText: "Enter Username", labelText: "Username"),
validator: (value) {
if (value?.isEmpty ?? true) {
return "Username cannot be empty";
}
return null;
},
onChanged: (value) {
name = value;
setState(() {});
},
),
// ignore: prefer_const_constructors
SizedBox(
height: 20.0,
),
TextFormField(
obscureText: true,
// ignore: prefer_const_constructors
decoration: InputDecoration(
hintText: "Enter Password", labelText: "Password"),
validator: (value) {
if (value?.isEmpty ?? true) {
return "Password cannot be empty";
} else if (value!.length < 6) {
return "Password length should be atleast 6";
}
return null;
},
),
Upvotes: 0
Reputation: 3548
The error you're facing came from null-safety, the value that you're getting from the validator method can be either null or either a String, so you may want to update your code to this example:
validator: (String? value) {
if (value!.isEmpty) {
return "Username cann't be empty";
}
return null;
}
You can learn more about null safety on official documentation:
Upvotes: 9
Reputation: 6337
You need to make the code null safe, to do that you have a few options, depending on what values you expect.
If you want a String
value only then set the initialValue
to ''
and update the validator condition to (value!.isEmpty)
add an !
after value
.
If the value really can be null, then add a test to ensure that members are only accessed when the value isn’t null, that is if initialValue
is set to null
, then you would need to update validator to check for null.
validator: (String? value) {
if (value != null && value.isEmpty) {
return "Username can't be empty";
}
return null;
}
If you want to know more about null-safety in dart check the official docs
Upvotes: 15