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?
In
CustomTextField, you have acontrollerfield that is initialized with aTextEditingController(), while thecontrollerparameter from the constructor is not used. It makesCustomTextFielduses its ownTextEditingControllerinstead of using the one passed from the parent widget. Fix it by applying these two changes: