I am a newbie of Flutter as my name states, i need some help from you guys. I am working with my login, registration form. When I register it throws no error, however when I try to login it shows null error:
class AuthDialog extends StatefulWidget {
@override
_AuthDialogState createState() => _AuthDialogState();
}
class _AuthDialogState extends State<AuthDialog> {
TextEditingController textControllerEmail;
FocusNode textFocusNodeEmail;
bool _isEditingEmail = false;
TextEditingController textControllerPassword;
FocusNode textFocusNodePassword;
bool _isEditingPassword = false;
bool _isLoading = false;
bool _isRegistering = false;
bool _isLoggingIn = false;
String loginStatus;
Color loginStringColor = Colors.green;
final scaffoldKey = new GlobalKey<ScaffoldState>();
final formKey = new GlobalKey<FormState>();
LoginPagePresenter _presenter;
String _validateEmail(String value) {
value = value.trim();
if (textControllerEmail.text.isNotEmpty) {
if (value.isEmpty) {
return 'Email can\'t be empty';
} else if (!value.contains(RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+"))) {
return 'Enter a correct email address';
}
}
return null;
}
void _submit() {
final form = formKey.currentState;
if (form.validate()) {
setState(() {
_isLoading = true;
form.save();
var user = new User(
textControllerEmail.text, textControllerPassword.text, null);
var db = new DatabaseHelper();
db.saveUser(user);
_isLoading = false;
});
}
}
void _login() {
final form = formKey.currentState;
if (form.validate()) {
setState(() {
_isLoading = true;
form.save();
_presenter.doLogin(
textControllerEmail.text, textControllerPassword.text);
});
}
}
String _validatePassword(String value) {
value = value.trim();
if (textControllerEmail.text.isNotEmpty) {
if (value.isEmpty) {
return 'Password can\'t be empty';
} else if (value.length < 6) {
return 'Length of password should be greater than 6';
}
}
return null;
}
@override
void initState() {
textControllerEmail = TextEditingController();
textControllerPassword = TextEditingController();
textControllerEmail.text = '';
textControllerPassword.text = '';
textFocusNodeEmail = FocusNode();
textFocusNodePassword = FocusNode();
super.initState();
}
@override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Theme.of(context).backgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
width: 400,
color: Theme.of(context).backgroundColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Center(
child: Text(
'NORTHERN NOMAD',
style: TextStyle(
color: Theme.of(context).textTheme.headline1.color,
fontSize: 24,
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
letterSpacing: 3,
),
),
),
SizedBox(height: 30),
Padding(
padding: const EdgeInsets.only(
left: 20.0,
bottom: 8,
),
child: Text(
'Email address',
textAlign: TextAlign.left,
style: TextStyle(
color: Theme.of(context).textTheme.subtitle2.color,
fontSize: 18,
// fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
// letterSpacing: 3,
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 20.0,
right: 20,
),
child: TextField(
focusNode: textFocusNodeEmail,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
controller: textControllerEmail,
autofocus: false,
onChanged: (value) {
setState(() {
_isEditingEmail = true;
});
},
onSubmitted: (value) => textControllerEmail.text = value,
//onSubmitted: (value) {
//textFocusNodeEmail.unfocus();
//FocusScope.of(context)
//.requestFocus(textFocusNodePassword);
// },
style: TextStyle(color: Colors.black),
decoration: InputDecoration(
border: new OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.blueGrey[800],
width: 3,
),
),
filled: true,
hintStyle: new TextStyle(
color: Colors.blueGrey[300],
),
hintText: "Email",
fillColor: Colors.white,
errorText: _isEditingEmail
? _validateEmail(textControllerEmail.text)
: null,
errorStyle: TextStyle(
fontSize: 12,
color: Colors.redAccent,
),
),
),
),
SizedBox(height: 20),
Padding(
padding: const EdgeInsets.only(
left: 20.0,
bottom: 8,
),
child: Text(
'Password',
textAlign: TextAlign.left,
style: TextStyle(
color: Theme.of(context).textTheme.subtitle2.color,
fontSize: 18,
fontWeight: FontWeight.bold,
// letterSpacing: 3,
),
),
),
new Form(
key: formKey,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
left: 20.0,
right: 20,
),
child: TextField(
focusNode: textFocusNodePassword,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
controller: textControllerPassword,
obscureText: true,
autofocus: false,
onChanged: (value) {
setState(() {
_isEditingPassword = true;
});
},
onSubmitted: (value) =>
textControllerPassword.text = value,
//onSubmitted: (value) {
//textFocusNodePassword.unfocus();
//FocusScope.of(context)
//.requestFocus(textFocusNodePassword);
//},
style: TextStyle(color: Colors.black),
decoration: InputDecoration(
border: new OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.blueGrey[800],
width: 3,
),
),
filled: true,
hintStyle: new TextStyle(
color: Colors.blueGrey[300],
),
hintText: "Password",
fillColor: Colors.white,
errorText: _isEditingPassword
? _validatePassword(
textControllerPassword.text)
: null,
errorStyle: TextStyle(
fontSize: 12,
color: Colors.redAccent,
),
),
),
),
],
)
),
//end
Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
flex: 1,
child: Container(
width: double.maxFinite,
child: TextButton(
style: TextButton.styleFrom(
primary: Colors.blueGrey.shade800,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
),
onPressed: () {
_login();
},
child: Padding(
padding: EdgeInsets.only(
top: 15.0,
bottom: 15.0,
),
child: _isLoggingIn
? SizedBox(
height: 16,
width: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
new AlwaysStoppedAnimation<Color>(
Colors.white,
),
),
)
: Text(
'Log in',
style: TextStyle(
fontSize: 14,
color: Colors.white,
),
),
),
),
),
),
SizedBox(width: 20),
Flexible(
flex: 1,
child: Container(
width: double.maxFinite,
child: TextButton(
style: TextButton.styleFrom(
primary: Colors.blueGrey.shade800,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
),
onPressed: () {
_submit();
},
child: Padding(
padding: EdgeInsets.only(
top: 15.0,
bottom: 15.0,
),
child: _isRegistering
? SizedBox(
height: 16,
width: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
new AlwaysStoppedAnimation<Color>(
Colors.white,
),
),
)
: Text(
'Sign up',
style: TextStyle(
fontSize: 14,
color: Colors.white,
),
),
),
),
),
),
],
),
),
loginStatus != null
? Center(
child: Padding(
padding: const EdgeInsets.only(
bottom: 20.0,
),
child: Text(
loginStatus,
style: TextStyle(
color: loginStringColor,
fontSize: 14,
// letterSpacing: 3,
),
),
),
)
: Container(),
Padding(
padding: const EdgeInsets.only(
left: 40.0,
right: 40.0,
),
child: Container(
height: 1,
width: double.maxFinite,
color: Colors.blueGrey[200],
),
),
SizedBox(height: 30),
SizedBox(height: 30),
],
),
),
),
),
);
}
}
This is the error when I run login:
════════ Exception caught by gesture ═══════════════════════════════════════════ The following NoSuchMethodError was thrown while handling a gesture: The method 'doLogin' was called on null. Receiver: null Tried calling: doLogin("[email protected]", "asdsadsad")
Here is my separated .dart file for doLogin
abstract class LoginPageContract {
void onLoginSuccess(User user);
void onLoginError(String error);
}
class LoginPagePresenter {
LoginPageContract _view;
RestData api = new RestData();
LoginPagePresenter(this._view);
//Simulator login
doLogin(String email, String password) {
api
.login(email, password)
.then((user) => _view.onLoginSuccess(user))
.catchError((onError) => _view.onLoginError(onError));
}
}
Would you call LoginPagePresenter class's constructor method?
Before
LoginPagePresenter _presenter;
After
LoginPagePresenter _presenter = LoginPagePresenter();