I am trying to check if a username already exists in my database when users are signing up. So I made a function to check the database and I wanted it to return a boolean, but as the call to the database returns a future, I made the function into a async function so I can await the response. As all async functions return a future I now have a future instead of a boolean. I want to be able to call my function multiple times within my build function, but I get a future instead of a boolean and if I try to add an await I have to make it async which means I would need to return a future not a widget.
Here is the widget. _account.isUsernameAvailable(value)
is the function that I want to return a boolean and below is my build function. From other answers I have read build future seems to be a popular option, but from what I can see the future value needs to be known before hand. In my case this is impossible. Any advice or help would be greatly appreciated.
final _account = Account();
@override
Widget build(BuildContext context) {
return loading ? Loading() : Scaffold(
appBar: AppBar(
title: Text('Sign Up'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Form(
key: _formKey,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: TextFormField(
onSaved: (value) {
_username = value.trim();
},
validator: (value) {
if (value.isEmpty) {
return 'Please enter a username';
} else if (_account.isUsernameAvailable(value)) {
return 'Username already exists';
}
return null;
},
decoration: InputDecoration(
hintText: 'Username',
),
),
),
Here's the code for the account class.
Future isUsernameAvailable(String username) async {
QuerySnapshot docs = await userCollection
.where('username', isEqualTo: username)
.getDocuments();
return docs.documents.isEmpty;
}
UPDATE:
As suggested I tried a then statement within a function.
bool _userExist = false;
checkUserValue<bool>(String user) {
_account
.isUsernameAvailable(user).then((val){
print(val);
if(val){
print ("UserName Already Exits");
_userExist = val;
}
else{
print ("UserName is Available");
_userExist = val;
}
});
print('here');
return _userExist;
}
and my widget looks like this now.
child: TextFormField(
onSaved: (value) {
_username = value.trim();
},
validator: (value) {
return checkUserValue(value) ? "Username taken" : null;
},
It seems to work but I need to validate twice for it to work. I think the value for _userExists
might be being set after the function returns somehow, but I'm not really sure why this behavior is happening. That being said, I do have a question why doesn't the function return before the .then() is complete?