In the following code, I’m trying to make a login screen. However, even after I type email and password, I get a popup telling me "Email or password is empty", which is expected inside my if check.
login_page.dart
import 'package:chat_app/auth/auth_service.dart';
import 'package:chat_app/components/custom_button.dart';
import 'package:chat_app/components/custom_textfield.dart';
import 'package:flutter/material.dart';
class LoginPage extends StatelessWidget {
final void Function()? onTap;
LoginPage({super.key, required this.onTap});
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
void login(BuildContext context) async {
final authService = AuthService();
final localContext = context;
String email = _emailController.text.trim();
String password = _passwordController.text.trim();
if (email.isEmpty || password.isEmpty) {
showDialog(
context: localContext,
builder: (context) => AlertDialog(
title: const Text("Error"),
content: const Text("Email or password is empty"),
actions: [
TextButton(
onPressed: () => Navigator.pop(localContext),
child: const Text("Ok"),
)
],
),
);
return; // Exit the method if email or password is empty
}
try {
await authService.signInWithEmailAndPassword(
_emailController.text.trim(), _passwordController.text.trim());
} catch (e) {
showDialog(
context: localContext,
builder: (localContext) => AlertDialog(
title: const Text("Error"),
content: Text(e.toString()),
actions: [
TextButton(
onPressed: () => Navigator.pop(localContext),
child: const Text("Ok"),
)
],
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.message_rounded,
size: 60,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 60),
Text(
"Welcome back, you've been missed",
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontSize: 16,
),
),
const SizedBox(height: 20),
CustomTextField(
hintText: "[email protected]",
obscureText: false,
controller: _emailController,
),
const SizedBox(height: 25),
CustomTextField(
hintText: "Password",
obscureText: true,
controller: _passwordController,
),
const SizedBox(height: 25),
CustomButton(text: "Login", onTap: () => login(context)),
const SizedBox(height: 25),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Not a member? ",
style: TextStyle(color: Theme.of(context).colorScheme.primary),
),
GestureDetector(
onTap: onTap,
child: Text(
"Register now",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.primary,
),
),
)
],
)
],
),
);
}
}
custom_textfield.dart
import 'package:flutter/material.dart';
class CustomTextField extends StatelessWidget {
final String hintText;
final bool obscureText;
final TextEditingController controller = TextEditingController();
CustomTextField({super.key, required controller, required this.hintText, required this.obscureText});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: TextField(
obscureText: obscureText,
controller: controller,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.tertiary,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.primary,
),
borderRadius: BorderRadius.circular(10),
),
fillColor: Theme.of(context).colorScheme.secondary,
filled: true,
hintText: hintText,
hintStyle: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
),
);
}
}
I just can’t understand how the controllers are appearing as an empty string like "", as if they aren’t receiving values at all. Any sugestions?
2
Answers
Just change the
onTap
Instead of this
To This
In
CustomTextField
, you have acontroller
field that is initialized with aTextEditingController()
, while thecontroller
parameter from the constructor is not used. It makesCustomTextField
uses its ownTextEditingController
instead of using the one passed from the parent widget. Fix it by applying these two changes: