"I’ve just started with Flutter and I’m trying to create a simple login application. Everything seems correct, but it looks like the navigation to the other page isn’t working.I noticed that in this part of the code, the username and password variables are empty, which is why the navigation is not happening.But I cant figure out why these vaiable are empty
if(_formKey.currentState!.validate()) {
_formKey.currentState!.save();
print("User: "+Username);
print("Password"+Password);
if(Username=="a" && Password=="a" ){
Get.to(Content());
}
This is complete code
late TextEditingController emailController;
late TextEditingController passwordController;
String Username="";
String Password="";
final _formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
emailController=TextEditingController();
passwordController=TextEditingController();
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(child: Text('Login-Register')),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
buildTextFormField(Icons.person, "Username", false,Username),
SizedBox(height: 15),
buildTextFormField(Icons.lock, "Password", true,Password),
SizedBox(height: 15),
SizedBox(
width: double.infinity,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStatePropertyAll(Colors.green)),
child: Text("Sign-In"),
onPressed: () {
if(_formKey.currentState!.validate()) {
_formKey.currentState!.save();
print("User: "+Username);
print("Password"+Password);
if(Username=="a" && Password=="a" ){
Get.to(Content());
}
}
})),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(onPressed: () {}, child: Text("Forgot Password")),
TextButton(onPressed: () {}, child: Text("Register")),
],
)
],
),
),
),
),
);
}
TextFormField buildTextFormField(
IconData icon, String hint, bool isPassword,String val) {
return TextFormField(
initialValue: "a",
onSaved: (value){
val=value!;
},
obscureText: isPassword,
decoration: InputDecoration(
prefixIcon: Icon(icon),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(40),
),
),
hintText: hint,
),
);
}
2
Answers
The val parameter in the
onSaved
method ofbuildTextFormField
method is being passed byvalue
, not byreference
hence doingval=value!
does not update theUsername
andPassword
variables in your widget state. You should directly update theUsername
andPassword
variables in the onSaved method. Follow the below modifications to your code:Modify the
buildTextFormField
method to take anonSave
callbackReplace the usage for username and password as shown below:
With the above setup, making calls to
_formKey.currentState!.save()
should correctly update the Username and Password variables, and your navigation logic should work as expected.Thanks for posting the full class! I took some time to read through all of it; Codefarmer’s answer is 100% on point, but I have a few small pieces of advice I wanted to share:
Single-line functions
If a function only has one expression, you can use
=>
instead of{}
to make it look a little nicer. These two function calls have the same behavior:Function vs. Class
Here’s some advice that will make your app run faster: if you want to clean up a build method, the best practice is to create another class instead of making a function. Functions are evaluated any time the widget is rebuilt, but widget classes are only rebuilt when needed.
Don’t do this:
Do this instead:
It’s more code to write, but it runs better 🙂
There were a couple of other small things; I’ll paste my version of the class below so you can take a look: