0

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?

  • If you really want to get a good answer you might want to post the code for the `Account` class. – Abiud Orina Feb 03 '20 at 18:58
  • See https://stackoverflow.com/q/53194662/10746978 – Naslausky Feb 03 '20 at 19:32
  • Have you tried Future isUsernameAvailable(String username) async {} instead? Then you should be able to use the "await" variant of the function in the rest of your code. By specifying Future as the return type, then it will return a bool in the future, if you await. – ArthurEKing Feb 03 '20 at 19:32
  • I looked at @Naslausky suggestion and it seems to work to a degree. It works the first time a name is entered but fails to update from there. The function itself works, but I think it returns before the then can finish. – Julian killingback Feb 03 '20 at 20:42

0 Answers0